extensive commit (see note)
The following changes are included: - Added support for GPC data type. - Added eager import of ``rattail.sil`` in ``before_render`` hook. - Removed ``rattail.pyramid.util`` module. - Added initial batch support: views, templates, creation from Product grid. - Added batch params template for ``PrintLabels`` provider. - Added support for ``rattail.LabelProfile`` class. - Improved Product grid to include filter/sort on Vendor.
This commit is contained in:
parent
563a10a283
commit
cf10fe19e8
|
@ -29,37 +29,21 @@
|
|||
from webhelpers.html import literal
|
||||
|
||||
import formalchemy
|
||||
# from formalchemy.fields import SelectFieldRenderer
|
||||
|
||||
import edbob
|
||||
from edbob.pyramid import Session
|
||||
from edbob.pyramid.forms import pretty_datetime
|
||||
|
||||
import rattail
|
||||
|
||||
|
||||
__all__ = ['PriceFieldRenderer', 'RegularPriceFieldRenderer', 'UpcFieldRenderer']
|
||||
|
||||
|
||||
class BatchIdFieldRenderer(formalchemy.FieldRenderer):
|
||||
class GPCFieldRenderer(formalchemy.TextFieldRenderer):
|
||||
"""
|
||||
Renders the :attr:`rattail.Batch.batch_id` field.
|
||||
Renderer for :class:`rattail.barcodes.GPC` fields.
|
||||
"""
|
||||
|
||||
def render_readonly(self, **kwargs):
|
||||
value = self.raw_value
|
||||
if value is None:
|
||||
return ''
|
||||
return '%08u' % int(value)
|
||||
|
||||
|
||||
# class BatchTerminalFieldRenderer(SelectFieldRenderer):
|
||||
# """
|
||||
# Renders a field whose value is a relationship to a
|
||||
# :class:`rattail.BatchTerminal` instance.
|
||||
# """
|
||||
|
||||
# def render(self, options, **kwargs):
|
||||
@property
|
||||
def length(self):
|
||||
# Hm, should maybe consider hard-coding this...?
|
||||
return len(str(rattail.GPC(0)))
|
||||
|
||||
|
||||
class PriceFieldRenderer(formalchemy.FieldRenderer):
|
||||
|
@ -98,42 +82,3 @@ class PriceWithExpirationFieldRenderer(PriceFieldRenderer):
|
|||
if price.ends:
|
||||
res += ' (%s)' % pretty_datetime(price.ends, from_='utc')
|
||||
return res
|
||||
|
||||
|
||||
class UpcFieldRenderer(formalchemy.TextFieldRenderer):
|
||||
"""
|
||||
Handles rendering for the product UPC field.
|
||||
"""
|
||||
|
||||
def render_readonly(self, **kwargs):
|
||||
value = self.raw_value
|
||||
if not value:
|
||||
return ''
|
||||
if isinstance(value, basestring):
|
||||
if value.isdigit():
|
||||
value = int(value)
|
||||
if isinstance(value, (int, long)):
|
||||
return '%013u' % value
|
||||
return self.stringify_value(value, as_html=True)
|
||||
|
||||
|
||||
def unique_batch_terminal_id(value, field=None):
|
||||
"""
|
||||
.. highlight:: python
|
||||
|
||||
Validator for the :class:`rattail.BatchTerminal` class to ensure that SIL
|
||||
IDs are not duplicated. For example::
|
||||
|
||||
from rattail.pyramid.forms import unique_batch_terminal_id
|
||||
|
||||
# fieldset = some_batch_terminal_fieldset_factory()
|
||||
fieldset.sil_id.set(validate=unique_batch_terminal_id)
|
||||
"""
|
||||
|
||||
if value:
|
||||
q = Session.query(rattail.BatchTerminal)
|
||||
q = q.filter(rattail.BatchTerminal.sil_id == value)
|
||||
if field.parent.edit:
|
||||
q = q.filter(rattail.BatchTerminal.uuid != field.parent.model.uuid)
|
||||
if q.count():
|
||||
raise formalchemy.ValidationError("SIL ID value must be unique within the system")
|
||||
|
|
|
@ -41,6 +41,9 @@ def before_render(event):
|
|||
# Import labels module so it's available if/when needed.
|
||||
import rattail.labels
|
||||
|
||||
# Import SIL module so it's available if/when needed.
|
||||
import rattail.sil
|
||||
|
||||
request = event.get('request') or threadlocal.get_current_request()
|
||||
|
||||
renderer_globals = event
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
<%inherit file="/base.mako" />
|
||||
${parent.body()}
|
|
@ -1,14 +0,0 @@
|
|||
<%inherit file="/batches/base.mako" />
|
||||
<%inherit file="/crud.mako" />
|
||||
|
||||
<%def name="crud_name()">Batch</%def>
|
||||
|
||||
<%def name="menu()">
|
||||
<p>${h.link_to("Back to Batches", url('batches.list'))}</p>
|
||||
% if fieldset.edit:
|
||||
<p>${h.link_to("View Batch Details", url('batch.details', uuid=fieldset.model.uuid))}</p>
|
||||
<p>${h.link_to("Execute this Batch", url('batch.execute', uuid=fieldset.model.uuid))}</p>
|
||||
% endif
|
||||
</%def>
|
||||
|
||||
${parent.body()}
|
|
@ -1,9 +0,0 @@
|
|||
|
||||
<table class="fieldset">
|
||||
<tr>
|
||||
<td class="label">Columns</td>
|
||||
<td>
|
||||
${columns|n}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
8
rattail/pyramid/templates/batches/crud.mako
Normal file
8
rattail/pyramid/templates/batches/crud.mako
Normal file
|
@ -0,0 +1,8 @@
|
|||
<%inherit file="/crud.mako" />
|
||||
|
||||
<%def name="context_menu_items()">
|
||||
<li>${h.link_to("Back to Batches", url('batches'))}</li>
|
||||
<li>${h.link_to("View Batch Rows", url('batch.rows', uuid=form.fieldset.model.uuid))}</li>
|
||||
</%def>
|
||||
|
||||
${parent.body()}
|
|
@ -1,12 +0,0 @@
|
|||
<%inherit file="/batches/base.mako" />
|
||||
<%inherit file="/index.mako" />
|
||||
|
||||
<%def name="title()">Batch : ${batch.name}</%def>
|
||||
|
||||
<%def name="menu()">
|
||||
<p>${h.link_to("Back to Batches", url('batches.list'))}</p>
|
||||
<p>${h.link_to("View Batch Properties", url('batch.edit', uuid=batch.uuid))}</p>
|
||||
<p>${h.link_to("Execute this Batch", url('batch.execute', uuid=batch.uuid))}</p>
|
||||
</%def>
|
||||
|
||||
${parent.body()}
|
|
@ -1,11 +0,0 @@
|
|||
<%inherit file="/batches/base.mako" />
|
||||
<%inherit file="/index.mako" />
|
||||
|
||||
<%def name="title()">Batch Dictionaries</%def>
|
||||
|
||||
<%def name="menu()">
|
||||
<p>${h.link_to("Back to Batches", url('batches.list'))}</p>
|
||||
## <p>${h.link_to("Create a New Dictionary", url('batch_dictionary'))}</p>
|
||||
</%def>
|
||||
|
||||
${parent.body()}
|
|
@ -1,9 +0,0 @@
|
|||
<%inherit file="/batches/base.mako" />
|
||||
<%inherit file="/crud.mako" />
|
||||
|
||||
<%def name="menu()">
|
||||
<p>${h.link_to("Back to Batches", url('batches.list'))}</p>
|
||||
<p>${h.link_to("Back to Dictionaries", url('batch_dictionaries'))}</p>
|
||||
</%def>
|
||||
|
||||
${parent.body()}
|
|
@ -1,8 +0,0 @@
|
|||
<table class="fieldset">
|
||||
<tr class="columns">
|
||||
<td class="label">Supported Columns</td>
|
||||
<td>
|
||||
${grid|n}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
|
@ -1,38 +1,5 @@
|
|||
<%inherit file="/batches/base.mako" />
|
||||
<%inherit file="/index.mako" />
|
||||
<%inherit file="/grid.mako" />
|
||||
|
||||
<%def name="title()">Batches</%def>
|
||||
|
||||
<%def name="head_tags()">
|
||||
<style type="text/css">
|
||||
|
||||
div.grid table tbody td.rowcount {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script language="javascript" type="text/javascript">
|
||||
|
||||
$(function() {
|
||||
$('div.grid table tbody td.action.execute a').live('click', function() {
|
||||
var tr = $(this).parents('tr:first');
|
||||
var desc = tr.find('td.description').text();
|
||||
if (confirm("Do you really wish to execute this batch?\n\n" + desc)) {
|
||||
var url = '${url('batch.execute', uuid='{uuid}')}';
|
||||
location.href = url.replace(/%7Buuid%7D/, get_uuid(this));
|
||||
}
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
</%def>
|
||||
|
||||
<%def name="menu()">
|
||||
## <p>${h.link_to("Create a New Batch", url('batch.new'))}</p>
|
||||
<p>${h.link_to("Manage Terminals", url('batch_terminals'))}</p>
|
||||
<p>${h.link_to("View Dictionaries", url('batch_dictionaries'))}</p>
|
||||
<p>${h.link_to("SIL Columns", url('sil_columns'))}</p>
|
||||
</%def>
|
||||
|
||||
${parent.body()}
|
||||
|
|
42
rattail/pyramid/templates/batches/params.mako
Normal file
42
rattail/pyramid/templates/batches/params.mako
Normal file
|
@ -0,0 +1,42 @@
|
|||
<%inherit file="/base.mako" />
|
||||
|
||||
<%def name="title()">Batch Parameters</%def>
|
||||
|
||||
<%def name="head_tags()">
|
||||
${parent.head_tags()}
|
||||
<script language="javascript" type="text/javascript">
|
||||
|
||||
$(function() {
|
||||
|
||||
$('#create-batch').click(function() {
|
||||
disable_button(this, "Creating batch");
|
||||
disable_button('#cancel');
|
||||
$('form').submit();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
</%def>
|
||||
|
||||
<%def name="batch_params()"></%def>
|
||||
|
||||
<p>Please provide the following values for your new batch:</p>
|
||||
<br />
|
||||
|
||||
<div class="form">
|
||||
|
||||
${h.form(request.get_referrer())}
|
||||
${h.hidden('provider', value=provider)}
|
||||
${h.hidden('params', value='True')}
|
||||
|
||||
${self.batch_params()}
|
||||
|
||||
<div class="buttons">
|
||||
<button type="button" id="create-batch">Create Batch</button>
|
||||
<button type="button" id="cancel" onclick="location.href = '${request.get_referrer()}';">Cancel</button>
|
||||
</div>
|
||||
|
||||
${h.end_form()}
|
||||
|
||||
</div>
|
19
rattail/pyramid/templates/batches/params/print_labels.mako
Normal file
19
rattail/pyramid/templates/batches/params/print_labels.mako
Normal file
|
@ -0,0 +1,19 @@
|
|||
<%inherit file="/batches/params.mako" />
|
||||
|
||||
<%def name="batch_params()">
|
||||
|
||||
<div class="field-wrapper">
|
||||
<label for="profile">Label Type</label>
|
||||
<div class="field">
|
||||
${h.select('profile', None, label_profiles)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field-wrapper">
|
||||
<label for="quantity">Quantity</label>
|
||||
<div class="field">${h.text('quantity', value=1)}</div>
|
||||
</div>
|
||||
|
||||
</%def>
|
||||
|
||||
${parent.body()}
|
40
rattail/pyramid/templates/batches/read.mako
Normal file
40
rattail/pyramid/templates/batches/read.mako
Normal file
|
@ -0,0 +1,40 @@
|
|||
<%inherit file="/batches/crud.mako" />
|
||||
|
||||
<%def name="context_menu_items()">
|
||||
${parent.context_menu_items()}
|
||||
<li>${h.link_to("Edit this Batch", url('batch.update', uuid=form.fieldset.model.uuid))}</li>
|
||||
<li>${h.link_to("Delete this Batch", url('batch.delete', uuid=form.fieldset.model.uuid))}</li>
|
||||
</%def>
|
||||
|
||||
${parent.body()}
|
||||
|
||||
<% batch = form.fieldset.model %>
|
||||
|
||||
<h2>Columns</h2>
|
||||
|
||||
<div class="grid full hoverable">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>SIL Name</th>
|
||||
<th>Display Name</th>
|
||||
<th>Description</th>
|
||||
<th>Data Type</th>
|
||||
<th>Visible</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
% for i, column in enumerate(batch.columns, 1):
|
||||
<tr class="${'odd' if i % 2 else 'even'}">
|
||||
<td>${column.name}</td>
|
||||
<td>${column.sil_name}</td>
|
||||
<td>${column.display_name}</td>
|
||||
<td>${column.description}</td>
|
||||
<td>${column.data_type}</td>
|
||||
<td>${column.visible}</td>
|
||||
</tr>
|
||||
% endfor
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
8
rattail/pyramid/templates/batches/rows/crud.mako
Normal file
8
rattail/pyramid/templates/batches/rows/crud.mako
Normal file
|
@ -0,0 +1,8 @@
|
|||
<%inherit file="/crud.mako" />
|
||||
|
||||
<%def name="context_menu_items()">
|
||||
<li>${h.link_to("Back to Batch", url('batch', uuid=form.fieldset.model.batch.uuid))}</li>
|
||||
<li>${h.link_to("Back to Batch Rows", url('batch.rows', uuid=form.fieldset.model.batch.uuid))}</li>
|
||||
</%def>
|
||||
|
||||
${parent.body()}
|
46
rattail/pyramid/templates/batches/rows/index.mako
Normal file
46
rattail/pyramid/templates/batches/rows/index.mako
Normal file
|
@ -0,0 +1,46 @@
|
|||
<%inherit file="/grid.mako" />
|
||||
|
||||
<%def name="title()">Batch Rows : ${batch.description}</%def>
|
||||
|
||||
<%def name="head_tags()">
|
||||
${parent.head_tags()}
|
||||
<script language="javascript" type="text/javascript">
|
||||
|
||||
$(function() {
|
||||
|
||||
$('#delete-results').click(function() {
|
||||
var msg = "This will delete all rows matching the current search.\n\n"
|
||||
+ "PLEASE NOTE that this may include some rows which are not visible "
|
||||
+ "on your screen.\n(I.e., if there is more than one \"page\" of results.)\n\n"
|
||||
+ "Are you sure you wish to delete these rows?";
|
||||
if (confirm(msg)) {
|
||||
disable_button(this, "Deleting rows");
|
||||
location.href = '${url('batch.rows.delete', uuid=batch.uuid)}';
|
||||
}
|
||||
});
|
||||
|
||||
$('#execute-batch').click(function() {
|
||||
if (confirm("Are you sure you wish to execute this batch?")) {
|
||||
disable_button(this, "Executing batch");
|
||||
location.href = '${url('batch.execute', uuid=batch.uuid)}';
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
</%def>
|
||||
|
||||
<%def name="context_menu_items()">
|
||||
<li>${h.link_to("Back to Batches", url('batches'))}</li>
|
||||
<li>${h.link_to("Back to Batch", url('batch', uuid=batch.uuid))}</li>
|
||||
</%def>
|
||||
|
||||
<%def name="tools()">
|
||||
<div class="buttons">
|
||||
<button type="button" id="delete-results">Delete Results</button>
|
||||
<button type="button" id="execute-batch">Execute Batch</button>
|
||||
</div>
|
||||
</%def>
|
||||
|
||||
${parent.body()}
|
|
@ -1,9 +0,0 @@
|
|||
<%inherit file="/batches/base.mako" />
|
||||
<%inherit file="/crud.mako" />
|
||||
|
||||
<%def name="menu()">
|
||||
<p>${h.link_to("Back to Batches", url('batches.list'))}</p>
|
||||
<p>${h.link_to("Back to SIL Columns", url('sil_columns'))}</p>
|
||||
</%def>
|
||||
|
||||
${parent.body()}
|
|
@ -1,10 +0,0 @@
|
|||
<%inherit file="/batches/base.mako" />
|
||||
<%inherit file="/index.mako" />
|
||||
|
||||
<%def name="title()">SIL Columns</%def>
|
||||
|
||||
<%def name="menu()">
|
||||
<p>${h.link_to("Back to Batches", url('batches.list'))}</p>
|
||||
</%def>
|
||||
|
||||
${parent.body()}
|
|
@ -1,24 +0,0 @@
|
|||
|
||||
<table class="wrapper">
|
||||
|
||||
<tr>
|
||||
<td><h2>Supported Fields</h2></td>
|
||||
## <td class="right">${h.link_to("Update Field List", '#', id='update-fields')}</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
${grid|n}
|
||||
|
||||
##<script language="javascript" type="text/javascript">
|
||||
##
|
||||
##$(function() {
|
||||
##
|
||||
## $('#update-fields').click(function() {
|
||||
## $('div.grid').load('${url('batches', action='update_terminal')}?uuid=${fieldset.model.uuid}');
|
||||
## return false;
|
||||
## });
|
||||
##
|
||||
##});
|
||||
##
|
||||
##</script>
|
|
@ -1,9 +0,0 @@
|
|||
<%inherit file="/batches/base.mako" />
|
||||
<%inherit file="/crud.mako" />
|
||||
|
||||
<%def name="menu()">
|
||||
<p>${h.link_to("Back to Batches", url('batches.list'))}</p>
|
||||
<p>${h.link_to("Back to Batch Terminals", url('batch_terminals'))}</p>
|
||||
</%def>
|
||||
|
||||
${parent.body()}
|
|
@ -1,11 +0,0 @@
|
|||
<%inherit file="/batches/base.mako" />
|
||||
<%inherit file="/index.mako" />
|
||||
|
||||
<%def name="title()">Batch Terminals</%def>
|
||||
|
||||
<%def name="menu()">
|
||||
<p>${h.link_to("Back to Batches", url('batches.list'))}</p>
|
||||
<p>${h.link_to("Create a New Terminal", url('batch_terminal.new'))}</p>
|
||||
</%def>
|
||||
|
||||
${parent.body()}
|
26
rattail/pyramid/templates/labels/profiles/crud.mako
Normal file
26
rattail/pyramid/templates/labels/profiles/crud.mako
Normal file
|
@ -0,0 +1,26 @@
|
|||
<%inherit file="/crud.mako" />
|
||||
|
||||
<%def name="head_tags()">
|
||||
${parent.head_tags()}
|
||||
<style type="text/css">
|
||||
|
||||
div.form div.field-wrapper.format textarea {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
</style>
|
||||
</%def>
|
||||
|
||||
<%def name="context_menu_items()">
|
||||
<li>${h.link_to("Back to Label Profiles", url('label_profiles'))}</li>
|
||||
% if form.updating:
|
||||
<% profile = form.fieldset.model %>
|
||||
<% printer = profile.get_printer() %>
|
||||
% if printer.required_settings:
|
||||
<li>${h.link_to("Edit Printer Settings", url('label_profile.printer_settings', uuid=profile.uuid))}</li>
|
||||
% endif
|
||||
<li>${h.link_to("View this Label Profile", url('label_profile.read', uuid=profile.uuid))}</li>
|
||||
% endif
|
||||
</%def>
|
||||
|
||||
${parent.body()}
|
11
rattail/pyramid/templates/labels/profiles/index.mako
Normal file
11
rattail/pyramid/templates/labels/profiles/index.mako
Normal file
|
@ -0,0 +1,11 @@
|
|||
<%inherit file="/grid.mako" />
|
||||
|
||||
<%def name="title()">Label Profiles</%def>
|
||||
|
||||
<%def name="context_menu_items()">
|
||||
% if request.has_perm('label_profiles.create'):
|
||||
<li>${h.link_to("Create a new Label Profile", url('label_profile.create'))}</li>
|
||||
% endif
|
||||
</%def>
|
||||
|
||||
${parent.body()}
|
48
rattail/pyramid/templates/labels/profiles/printer.mako
Normal file
48
rattail/pyramid/templates/labels/profiles/printer.mako
Normal file
|
@ -0,0 +1,48 @@
|
|||
<%inherit file="/base.mako" />
|
||||
|
||||
<%def name="title()">Printer Settings</%def>
|
||||
|
||||
<%def name="context_menu_items()">
|
||||
<li>${h.link_to("Back to Label Profiles", url('label_profiles'))}</li>
|
||||
<li>${h.link_to("View this Label Profile", url('label_profile.read', uuid=profile.uuid))}</li>
|
||||
<li>${h.link_to("Edit this Label Profile", url('label_profile.update', uuid=profile.uuid))}</li>
|
||||
</%def>
|
||||
|
||||
<div class="form-wrapper">
|
||||
|
||||
<ul class="context-menu">
|
||||
${self.context_menu_items()}
|
||||
</ul>
|
||||
|
||||
<div class="form">
|
||||
|
||||
<div class="field-wrapper">
|
||||
<label>Label Profile</label>
|
||||
<div class="field">${profile.description}</div>
|
||||
</div>
|
||||
|
||||
<div class="field-wrapper">
|
||||
<label>Printer Spec</label>
|
||||
<div class="field">${profile.printer_spec}</div>
|
||||
</div>
|
||||
|
||||
${h.form(request.current_route_url())}
|
||||
|
||||
% for name, display in printer.required_settings.iteritems():
|
||||
<div class="field-wrapper">
|
||||
<label for="${name}">${display}</label>
|
||||
<div class="field">
|
||||
${h.text(name, value=profile.get_printer_setting(name))}
|
||||
</div>
|
||||
</div>
|
||||
% endfor
|
||||
|
||||
<div class="buttons">
|
||||
${h.submit('update', "Update")}
|
||||
<button type="button" onclick="location.href = '${url('label_profile.read', uuid=profile.uuid)}';">Cancel</button>
|
||||
</div>
|
||||
|
||||
${h.end_form()}
|
||||
</div>
|
||||
|
||||
</div>
|
32
rattail/pyramid/templates/labels/profiles/read.mako
Normal file
32
rattail/pyramid/templates/labels/profiles/read.mako
Normal file
|
@ -0,0 +1,32 @@
|
|||
<%inherit file="/labels/profiles/crud.mako" />
|
||||
|
||||
<%def name="context_menu_items()">
|
||||
<li>${h.link_to("Back to Label Profiles", url('label_profiles'))}</li>
|
||||
% if form.readonly and request.has_perm('label_profiles.update'):
|
||||
<% profile = form.fieldset.model %>
|
||||
<% printer = profile.get_printer() %>
|
||||
<li>${h.link_to("Edit this Label Profile", url('label_profile.update', uuid=form.fieldset.model.uuid))}</li>
|
||||
% if printer.required_settings:
|
||||
<li>${h.link_to("Edit Printer Settings", url('label_profile.printer_settings', uuid=profile.uuid))}</li>
|
||||
% endif
|
||||
% endif
|
||||
</%def>
|
||||
|
||||
${parent.body()}
|
||||
|
||||
<% profile = form.fieldset.model %>
|
||||
<% printer = profile.get_printer() %>
|
||||
|
||||
% if printer.required_settings:
|
||||
<h2>Printer Settings</h2>
|
||||
|
||||
<div class="form">
|
||||
% for name, display in printer.required_settings.iteritems():
|
||||
<div class="field-wrapper">
|
||||
<label>${display}</label>
|
||||
<div class="field">${profile.get_printer_setting(name) or ''}</div>
|
||||
</div>
|
||||
% endfor
|
||||
</div>
|
||||
|
||||
% endif
|
27
rattail/pyramid/templates/products/batch.mako
Normal file
27
rattail/pyramid/templates/products/batch.mako
Normal file
|
@ -0,0 +1,27 @@
|
|||
<%inherit file="/base.mako" />
|
||||
|
||||
<%def name="title()">Create Products Batch</%def>
|
||||
|
||||
<%def name="context_menu_items()">
|
||||
<li>${h.link_to("Back to Products", url('products'))}</li>
|
||||
</%def>
|
||||
|
||||
<div class="form">
|
||||
|
||||
${h.form(request.current_route_url())}
|
||||
|
||||
<div class="field-wrapper">
|
||||
<label for="provider">Batch Type</label>
|
||||
<div class="field">
|
||||
${h.select('provider', None, providers)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
${h.submit('create', "Create Batch")}
|
||||
<button type="button" onclick="location.href = '${url('products')}';">Cancel</button>
|
||||
</div>
|
||||
|
||||
${h.end_form()}
|
||||
|
||||
</div>
|
|
@ -33,7 +33,7 @@
|
|||
}
|
||||
|
||||
</style>
|
||||
% if edbob.config.getboolean('rattail.labels', 'enabled', default=False):
|
||||
% if label_profiles and request.has_perm('products.print_labels'):
|
||||
<script language="javascript" type="text/javascript">
|
||||
|
||||
$(function() {
|
||||
|
@ -45,18 +45,22 @@
|
|||
$('#label-quantity').focus();
|
||||
} else {
|
||||
$.ajax({
|
||||
url: '${url('products.print_label')}',
|
||||
url: '${url('products.print_labels')}',
|
||||
data: {
|
||||
'uuid': get_uuid(this),
|
||||
'product': get_uuid(this),
|
||||
'profile': $('#label-profile').val(),
|
||||
'quantity': quantity,
|
||||
},
|
||||
success: function(data) {
|
||||
if (data.error) {
|
||||
alert("An error occurred while attempting to print:\n\n" + data.error);
|
||||
} else if (quantity == '1') {
|
||||
alert("1 label has been printed.");
|
||||
} else {
|
||||
alert(quantity + " labels have been printed.");
|
||||
}
|
||||
},
|
||||
});
|
||||
if (quantity == '1') {
|
||||
alert("1 label has been printed.");
|
||||
} else {
|
||||
alert(quantity + " labels have been printed.");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
@ -67,7 +71,7 @@
|
|||
</%def>
|
||||
|
||||
<%def name="tools()">
|
||||
% if edbob.config.getboolean('rattail.labels', 'enabled', default=False):
|
||||
% if label_profiles and request.has_perm('products.print_labels'):
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -78,8 +82,8 @@
|
|||
<tbody>
|
||||
<td>
|
||||
<select name="label-profile" id="label-profile">
|
||||
% for profile in rattail.labels.iter_profiles():
|
||||
<option value="${profile.name}">${profile.display_name}</option>
|
||||
% for profile in label_profiles:
|
||||
<option value="${profile.uuid}">${profile.description}</option>
|
||||
% endfor
|
||||
</select>
|
||||
</td>
|
||||
|
@ -91,4 +95,10 @@
|
|||
% endif
|
||||
</%def>
|
||||
|
||||
<%def name="context_menu_items()">
|
||||
% if request.has_perm('batches.create'):
|
||||
<li>${h.link_to("Create Batch from Results", url('products.create_batch'))}</li>
|
||||
% endif
|
||||
</%def>
|
||||
|
||||
${parent.body()}
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2012 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
# Rattail is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, either version 3 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with Rattail. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
"""
|
||||
``rattail.pyramid.util`` -- Utilities
|
||||
"""
|
||||
|
||||
from pyramid import threadlocal
|
||||
from webhelpers.html import tags
|
||||
|
||||
import edbob
|
||||
from edbob.pyramid import Session
|
||||
|
||||
import rattail
|
||||
|
||||
|
||||
def get_column(sil_name):
|
||||
"""
|
||||
Returns the :class:`rattail.SilColumn` instance with the given SIL name.
|
||||
"""
|
||||
|
||||
q = Session.query(rattail.SilColumn)
|
||||
q = q.filter(rattail.SilColumn.sil_name == sil_name)
|
||||
if q.count() == 1:
|
||||
return q.one()
|
||||
|
||||
|
||||
def get_dictionary(name, flash=False):
|
||||
"""
|
||||
Returns the :class:`rattail.BatchDictionary` instance with the given name.
|
||||
"""
|
||||
|
||||
q = Session.query(rattail.BatchDictionary)
|
||||
q = q.filter(rattail.BatchDictionary.name == name)
|
||||
if q.count() == 1:
|
||||
return q.one()
|
||||
|
||||
if flash:
|
||||
request = threadlocal.get_current_request()
|
||||
dct = tags.link_to("Batch Dictionary", request.route_url('batch_dictionaries'))
|
||||
request.session.flash("Hm, I couldn't find the '%s' %s." % (name, dct))
|
||||
|
||||
|
||||
def get_terminal(key=None, default='rattail', title="Rattail"):
|
||||
"""
|
||||
Returns the :class:`rattail.BatchTerminal` instance with the given SIL ID.
|
||||
|
||||
If ``key`` is specified, it will be used to obtain the SIL ID from config.
|
||||
If no key is given, or config contains no appropriate value, then
|
||||
``default`` will be used as the SIL ID.
|
||||
|
||||
``title`` is used for a flash message, should no such terminal be found.
|
||||
|
||||
.. highlight:: ini
|
||||
|
||||
Given a ``key`` value of ``'products'``, a SIL ID of ``'rattail.locsms'``
|
||||
should be configured like this::
|
||||
|
||||
[rattail.pyramid]
|
||||
batch_terminal.products = rattail.locsms
|
||||
"""
|
||||
|
||||
if key:
|
||||
sil_id = edbob.config.get('rattail.pyramid', 'batch_terminal.%s' % key,
|
||||
default=default)
|
||||
assert sil_id
|
||||
|
||||
q = Session.query(rattail.BatchTerminal)
|
||||
q = q.filter(rattail.BatchTerminal.sil_id == sil_id)
|
||||
if q.count() == 1:
|
||||
return q.one()
|
||||
|
||||
request = threadlocal.get_current_request()
|
||||
terminal = tags.link_to("Batch Terminal", request.route_url('batch_terminals'))
|
||||
request.session.flash("Hm, I couldn't find a %s for %s." % (terminal, title))
|
File diff suppressed because it is too large
Load diff
35
rattail/pyramid/views/batches/__init__.py
Normal file
35
rattail/pyramid/views/batches/__init__.py
Normal file
|
@ -0,0 +1,35 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2012 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
# Rattail is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, either version 3 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with Rattail. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
"""
|
||||
``rattail.pyramid.views.batches`` -- Batch Views
|
||||
"""
|
||||
|
||||
from rattail.pyramid.views.batches.params import *
|
||||
|
||||
|
||||
def includeme(config):
|
||||
config.include('rattail.pyramid.views.batches.core')
|
||||
config.include('rattail.pyramid.views.batches.params')
|
||||
config.include('rattail.pyramid.views.batches.rows')
|
174
rattail/pyramid/views/batches/core.py
Normal file
174
rattail/pyramid/views/batches/core.py
Normal file
|
@ -0,0 +1,174 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2012 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
# Rattail is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, either version 3 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with Rattail. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
"""
|
||||
``rattail.pyramid.views.batches.core`` -- Core Batch Views
|
||||
"""
|
||||
|
||||
import threading
|
||||
|
||||
from pyramid.httpexceptions import HTTPFound
|
||||
from pyramid.renderers import render_to_response
|
||||
|
||||
from webhelpers.html import tags
|
||||
|
||||
import edbob
|
||||
from edbob.pyramid import Session
|
||||
from edbob.pyramid.forms import EnumFieldRenderer
|
||||
from edbob.pyramid.progress import SessionProgress
|
||||
from edbob.pyramid.views import SearchableAlchemyGridView, CrudView, View
|
||||
|
||||
import rattail
|
||||
from rattail import batches
|
||||
|
||||
|
||||
class BatchesGrid(SearchableAlchemyGridView):
|
||||
|
||||
mapped_class = rattail.Batch
|
||||
config_prefix = 'batches'
|
||||
sort = 'id'
|
||||
|
||||
def filter_map(self):
|
||||
return self.make_filter_map(
|
||||
exact=['id'],
|
||||
ilike=['source', 'destination', 'description'])
|
||||
|
||||
def filter_config(self):
|
||||
return self.make_filter_config(
|
||||
filter_label_id="ID")
|
||||
|
||||
def sort_map(self):
|
||||
return self.make_sort_map('source', 'id', 'destination', 'description')
|
||||
|
||||
def query(self):
|
||||
q = self.make_query()
|
||||
q = q.filter(rattail.Batch.executed == None)
|
||||
return q
|
||||
|
||||
def grid(self):
|
||||
g = self.make_grid()
|
||||
g.configure(
|
||||
include=[
|
||||
g.source,
|
||||
g.id.label("ID"),
|
||||
g.destination,
|
||||
g.description,
|
||||
g.rowcount.label("Row Count"),
|
||||
],
|
||||
readonly=True)
|
||||
if self.request.has_perm('batches.read'):
|
||||
def rows(row):
|
||||
return tags.link_to("View Rows", self.request.route_url(
|
||||
'batch.rows', uuid=row.uuid))
|
||||
g.add_column('rows', "", rows)
|
||||
g.clickable = True
|
||||
g.click_route_name = 'batch'
|
||||
if self.request.has_perm('batches.update'):
|
||||
g.editable = True
|
||||
g.edit_route_name = 'batch.update'
|
||||
if self.request.has_perm('batches.delete'):
|
||||
g.deletable = True
|
||||
g.delete_route_name = 'batch.delete'
|
||||
return g
|
||||
|
||||
|
||||
class BatchCrud(CrudView):
|
||||
|
||||
mapped_class = rattail.Batch
|
||||
home_route = 'batches'
|
||||
|
||||
def fieldset(self, model):
|
||||
fs = self.make_fieldset(model)
|
||||
fs.action_type.set(renderer=EnumFieldRenderer(rattail.BATCH_ACTION))
|
||||
fs.configure(
|
||||
include=[
|
||||
fs.source,
|
||||
fs.id.label("ID"),
|
||||
fs.destination,
|
||||
fs.action_type,
|
||||
fs.description,
|
||||
fs.rowcount.label("Row Count").readonly(),
|
||||
])
|
||||
return fs
|
||||
|
||||
def post_delete(self, batch):
|
||||
batch.drop_table()
|
||||
|
||||
|
||||
class ExecuteBatch(View):
|
||||
|
||||
def execute_batch(self, batch):
|
||||
session = edbob.Session()
|
||||
batch = session.merge(batch)
|
||||
|
||||
progress = SessionProgress(self.request.session, 'batch.execute')
|
||||
progress.session['success_msg'] = "Batch \"%s\" has been executed." % batch.description
|
||||
progress.session['success_url'] = self.request.route_url('batches')
|
||||
|
||||
if batch.execute(progress):
|
||||
session.commit()
|
||||
else:
|
||||
session.rollback()
|
||||
session.close()
|
||||
|
||||
def __call__(self):
|
||||
uuid = self.request.matchdict['uuid']
|
||||
batch = Session.query(rattail.Batch).get(uuid) if uuid else None
|
||||
if not batch:
|
||||
return HTTPFound(location=self.request.route_url('batches'))
|
||||
|
||||
thread = threading.Thread(target=self.execute_batch, args=(batch,))
|
||||
thread.start()
|
||||
kwargs = {
|
||||
'key': 'batch.execute',
|
||||
'cancel_url': self.request.route_url('batch.rows', uuid=batch.uuid),
|
||||
'cancel_msg': "Batch execution was cancelled.",
|
||||
}
|
||||
return render_to_response('/progress.mako', kwargs, request=self.request)
|
||||
|
||||
|
||||
def includeme(config):
|
||||
|
||||
config.add_route('batches', '/batches')
|
||||
config.add_view(BatchesGrid, route_name='batches',
|
||||
renderer='/batches/index.mako',
|
||||
permission='batches.list')
|
||||
|
||||
config.add_route('batch', '/batches/{uuid}')
|
||||
config.add_view(BatchCrud, attr='read', route_name='batch',
|
||||
renderer='/batches/read.mako',
|
||||
permission='batches.read')
|
||||
|
||||
config.add_route('batch.update', '/batches/{uuid}/edit')
|
||||
config.add_view(BatchCrud, attr='update', route_name='batch.update',
|
||||
renderer='/batches/crud.mako',
|
||||
permission='batches.update')
|
||||
|
||||
config.add_route('batch.delete', '/batches/{uuid}/delete')
|
||||
config.add_view(BatchCrud, attr='delete', route_name='batch.delete',
|
||||
permission='batches.delete')
|
||||
|
||||
config.add_route('batch.execute', '/batches/{uuid}/execute')
|
||||
config.add_view(ExecuteBatch, route_name='batch.execute',
|
||||
permission='batches.execute')
|
52
rattail/pyramid/views/batches/params/__init__.py
Normal file
52
rattail/pyramid/views/batches/params/__init__.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2012 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
# Rattail is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, either version 3 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with Rattail. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
"""
|
||||
``rattail.pyramid.views.batches.params`` -- Batch Parameter Views
|
||||
"""
|
||||
|
||||
from edbob.pyramid.views import View
|
||||
|
||||
|
||||
__all__ = ['BatchParamsView']
|
||||
|
||||
|
||||
class BatchParamsView(View):
|
||||
|
||||
provider_name = None
|
||||
|
||||
def render_kwargs(self):
|
||||
return {}
|
||||
|
||||
def __call__(self):
|
||||
if self.request.POST:
|
||||
if self.set_batch_params():
|
||||
return HTTPFound(location=self.request.get_referer())
|
||||
kwargs = self.render_kwargs()
|
||||
kwargs['provider'] = self.provider_name
|
||||
return kwargs
|
||||
|
||||
|
||||
def includeme(config):
|
||||
config.include('rattail.pyramid.views.batches.params.labels')
|
51
rattail/pyramid/views/batches/params/labels.py
Normal file
51
rattail/pyramid/views/batches/params/labels.py
Normal file
|
@ -0,0 +1,51 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2012 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
# Rattail is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, either version 3 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with Rattail. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
"""
|
||||
``rattail.pyramid.views.batches.params.printlabels`` -- Print Labels Batch
|
||||
"""
|
||||
|
||||
from edbob.pyramid import Session
|
||||
|
||||
import rattail
|
||||
from rattail.pyramid.views.batches.params import BatchParamsView
|
||||
|
||||
|
||||
class PrintLabels(BatchParamsView):
|
||||
|
||||
provider_name = 'print_labels'
|
||||
|
||||
def render_kwargs(self):
|
||||
q = Session.query(rattail.LabelProfile)
|
||||
q = q.order_by(rattail.LabelProfile.ordinal)
|
||||
profiles = [(x.code, x.description) for x in q]
|
||||
return {'label_profiles': profiles}
|
||||
|
||||
|
||||
def includeme(config):
|
||||
|
||||
config.add_route('batch_params.print_labels', '/batches/params/print-labels')
|
||||
config.add_view(PrintLabels, route_name='batch_params.print_labels',
|
||||
renderer='/batches/params/print_labels.mako',
|
||||
permission='batches.print_labels')
|
219
rattail/pyramid/views/batches/rows.py
Normal file
219
rattail/pyramid/views/batches/rows.py
Normal file
|
@ -0,0 +1,219 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2012 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
# Rattail is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, either version 3 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with Rattail. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
"""
|
||||
``rattail.pyramid.views.batches.rows`` -- Batch Row Views
|
||||
"""
|
||||
|
||||
from pyramid.httpexceptions import HTTPFound
|
||||
|
||||
from edbob.pyramid import Session
|
||||
from edbob.pyramid.views import SearchableAlchemyGridView, CrudView
|
||||
|
||||
import rattail
|
||||
from rattail.pyramid.forms import GPCFieldRenderer
|
||||
|
||||
|
||||
def field_with_renderer(field, column):
|
||||
|
||||
if column.sil_name == 'F01': # UPC
|
||||
field = field.with_renderer(GPCFieldRenderer)
|
||||
|
||||
elif column.sil_name == 'F95': # Shelf Tag Type
|
||||
q = Session.query(rattail.LabelProfile)
|
||||
q = q.order_by(rattail.LabelProfile.ordinal)
|
||||
field = field.dropdown(options=[(x.description, x.code) for x in q])
|
||||
|
||||
return field
|
||||
|
||||
|
||||
def BatchRowsGrid(request):
|
||||
uuid = request.matchdict['uuid']
|
||||
batch = Session.query(rattail.Batch).get(uuid) if uuid else None
|
||||
if not batch:
|
||||
return HTTPFound(location=request.route_url('batches'))
|
||||
|
||||
class BatchRowsGrid(SearchableAlchemyGridView):
|
||||
|
||||
mapped_class = batch.rowclass
|
||||
config_prefix = 'batch.%s' % batch.uuid
|
||||
sort = 'ordinal'
|
||||
|
||||
def filter_map(self):
|
||||
fmap = self.make_filter_map()
|
||||
for column in batch.columns:
|
||||
if column.visible:
|
||||
if column.data_type.startswith('CHAR'):
|
||||
fmap[column.name] = self.filter_ilike(
|
||||
getattr(batch.rowclass, column.name))
|
||||
else:
|
||||
fmap[column.name] = self.filter_exact(
|
||||
getattr(batch.rowclass, column.name))
|
||||
return fmap
|
||||
|
||||
def filter_config(self):
|
||||
config = self.make_filter_config()
|
||||
for column in batch.columns:
|
||||
if column.visible:
|
||||
config['filter_label_%s' % column.name] = column.display_name
|
||||
return config
|
||||
|
||||
def grid(self):
|
||||
g = self.make_grid()
|
||||
|
||||
include = [g.ordinal.label("Row")]
|
||||
for column in batch.columns:
|
||||
if column.visible:
|
||||
field = getattr(g, column.name)
|
||||
field = field_with_renderer(field, column)
|
||||
field = field.label(column.display_name)
|
||||
include.append(field)
|
||||
g.column_titles[field.key] = '%s - %s - %s' % (
|
||||
column.sil_name, column.description, column.data_type)
|
||||
|
||||
g.configure(include=include, readonly=True)
|
||||
|
||||
route_kwargs = lambda x: {'batch_uuid': x.batch.uuid, 'uuid': x.uuid}
|
||||
|
||||
if self.request.has_perm('batch_rows.read'):
|
||||
g.clickable = True
|
||||
g.click_route_name = 'batch_row.read'
|
||||
g.click_route_kwargs = route_kwargs
|
||||
|
||||
if self.request.has_perm('batch_rows.update'):
|
||||
g.editable = True
|
||||
g.edit_route_name = 'batch_row.update'
|
||||
g.edit_route_kwargs = route_kwargs
|
||||
|
||||
if self.request.has_perm('batch_rows.delete'):
|
||||
g.deletable = True
|
||||
g.delete_route_name = 'batch_row.delete'
|
||||
g.delete_route_kwargs = route_kwargs
|
||||
|
||||
return g
|
||||
|
||||
def render_kwargs(self):
|
||||
return {'batch': batch}
|
||||
|
||||
grid = BatchRowsGrid(request)
|
||||
grid.batch = batch
|
||||
return grid
|
||||
|
||||
|
||||
def batch_rows_grid(request):
|
||||
grid = BatchRowsGrid(request)
|
||||
return grid()
|
||||
|
||||
|
||||
def batch_rows_delete(request):
|
||||
grid = BatchRowsGrid(request)
|
||||
grid._filter_config = grid.filter_config()
|
||||
rows = grid.make_query()
|
||||
count = rows.count()
|
||||
rows.delete(synchronize_session=False)
|
||||
request.session.flash("Deleted %d rows from batch." % count)
|
||||
return HTTPFound(location=request.route_url('batch.rows', uuid=grid.batch.uuid))
|
||||
|
||||
|
||||
def batch_row_crud(request, attr):
|
||||
batch_uuid = request.matchdict['batch_uuid']
|
||||
batch = Session.query(rattail.Batch).get(batch_uuid)
|
||||
if not batch:
|
||||
return HTTPFound(location=request.route_url('batches'))
|
||||
|
||||
row_uuid = request.matchdict['uuid']
|
||||
row = Session.query(batch.rowclass).get(row_uuid)
|
||||
if not row:
|
||||
return HTTPFound(location=request.route_url('batch', uuid=batch.uuid))
|
||||
|
||||
class BatchRowCrud(CrudView):
|
||||
|
||||
mapped_class = batch.rowclass
|
||||
pretty_name = "Batch Row"
|
||||
|
||||
@property
|
||||
def home_url(self):
|
||||
return self.request.route_url('batch.rows', uuid=batch.uuid)
|
||||
|
||||
@property
|
||||
def cancel_url(self):
|
||||
return self.home_url
|
||||
|
||||
def fieldset(self, model):
|
||||
fs = self.make_fieldset(model)
|
||||
|
||||
include = [fs.ordinal.label("Row Number").readonly()]
|
||||
for column in batch.columns:
|
||||
field = getattr(fs, column.name)
|
||||
field = field_with_renderer(field, column)
|
||||
field = field.label(column.display_name)
|
||||
include.append(field)
|
||||
|
||||
fs.configure(include=include)
|
||||
return fs
|
||||
|
||||
def flash_delete(self, row):
|
||||
self.request.session.flash("Batch Row %d has been deleted."
|
||||
% row.ordinal)
|
||||
|
||||
def post_delete(self, model):
|
||||
batch.rowcount -= 1
|
||||
|
||||
crud = BatchRowCrud(request)
|
||||
return getattr(crud, attr)()
|
||||
|
||||
def batch_row_read(request):
|
||||
return batch_row_crud(request, 'read')
|
||||
|
||||
def batch_row_update(request):
|
||||
return batch_row_crud(request, 'update')
|
||||
|
||||
def batch_row_delete(request):
|
||||
return batch_row_crud(request, 'delete')
|
||||
|
||||
|
||||
def includeme(config):
|
||||
|
||||
config.add_route('batch.rows', '/batches/{uuid}/rows')
|
||||
config.add_view(batch_rows_grid, route_name='batch.rows',
|
||||
renderer='/batches/rows/index.mako',
|
||||
permission='batches.read')
|
||||
|
||||
config.add_route('batch.rows.delete', '/batches/{uuid}/rows/delete')
|
||||
config.add_view(batch_rows_delete, route_name='batch.rows.delete',
|
||||
permission='batch_rows.delete')
|
||||
|
||||
config.add_route('batch_row.read', '/batches/{batch_uuid}/{uuid}')
|
||||
config.add_view(batch_row_read, route_name='batch_row.read',
|
||||
renderer='/batches/rows/crud.mako',
|
||||
permission='batch_rows.read')
|
||||
|
||||
config.add_route('batch_row.update', '/batches/{batch_uuid}/{uuid}/edit')
|
||||
config.add_view(batch_row_update, route_name='batch_row.update',
|
||||
renderer='/batches/rows/crud.mako',
|
||||
permission='batch_rows.update')
|
||||
|
||||
config.add_route('batch_row.delete', '/batches/{batch_uuid}/{uuid}/delete')
|
||||
config.add_view(batch_row_delete, route_name='batch_row.delete',
|
||||
permission='batch_rows.delete')
|
172
rattail/pyramid/views/labels.py
Normal file
172
rattail/pyramid/views/labels.py
Normal file
|
@ -0,0 +1,172 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2012 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
# Rattail is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, either version 3 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with Rattail. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
"""
|
||||
``rattail.pyramid.views.labels`` -- Label Views
|
||||
"""
|
||||
|
||||
from pyramid.httpexceptions import HTTPFound
|
||||
|
||||
import formalchemy
|
||||
|
||||
from webhelpers.html import HTML
|
||||
|
||||
from edbob.pyramid import Session
|
||||
from edbob.pyramid.views import SearchableAlchemyGridView, CrudView
|
||||
|
||||
import rattail
|
||||
|
||||
|
||||
class ProfilesGrid(SearchableAlchemyGridView):
|
||||
|
||||
mapped_class = rattail.LabelProfile
|
||||
config_prefix = 'label_profiles'
|
||||
sort = 'ordinal'
|
||||
|
||||
def filter_map(self):
|
||||
return self.make_filter_map(
|
||||
exact=['code'],
|
||||
ilike=['description'])
|
||||
|
||||
def sort_map(self):
|
||||
return self.make_sort_map('ordinal', 'code', 'description')
|
||||
|
||||
def grid(self):
|
||||
g = self.make_grid()
|
||||
g.configure(
|
||||
include=[
|
||||
g.ordinal,
|
||||
g.code,
|
||||
g.description,
|
||||
],
|
||||
readonly=True)
|
||||
if self.request.has_perm('label_profiles.read'):
|
||||
g.clickable = True
|
||||
g.click_route_name = 'label_profile.read'
|
||||
if self.request.has_perm('label_profiles.update'):
|
||||
g.editable = True
|
||||
g.edit_route_name = 'label_profile.update'
|
||||
if self.request.has_perm('label_profiles.delete'):
|
||||
g.deletable = True
|
||||
g.delete_route_name = 'label_profile.delete'
|
||||
return g
|
||||
|
||||
|
||||
class ProfileCrud(CrudView):
|
||||
|
||||
mapped_class = rattail.LabelProfile
|
||||
home_route = 'label_profiles'
|
||||
pretty_name = "Label Profile"
|
||||
update_cancel_route = 'label_profile.read'
|
||||
|
||||
def fieldset(self, model):
|
||||
|
||||
class FormatFieldRenderer(formalchemy.TextAreaFieldRenderer):
|
||||
|
||||
def render_readonly(self, **kwargs):
|
||||
value = self.raw_value
|
||||
if not value:
|
||||
return ''
|
||||
return HTML.tag('pre', c=value)
|
||||
|
||||
def render(self, **kwargs):
|
||||
kwargs.setdefault('size', (80, 8))
|
||||
return super(FormatFieldRenderer, self).render(**kwargs)
|
||||
|
||||
fs = self.make_fieldset(model)
|
||||
fs.format.set(renderer=FormatFieldRenderer)
|
||||
fs.configure(
|
||||
include=[
|
||||
fs.ordinal,
|
||||
fs.code,
|
||||
fs.description,
|
||||
fs.printer_spec,
|
||||
fs.formatter_spec,
|
||||
fs.format,
|
||||
])
|
||||
return fs
|
||||
|
||||
def post_save_url(self, form):
|
||||
return self.request.route_url('label_profile.read',
|
||||
uuid=form.fieldset.model.uuid)
|
||||
|
||||
|
||||
def printer_settings(request):
|
||||
uuid = request.matchdict['uuid']
|
||||
profile = Session.query(rattail.LabelProfile).get(uuid) if uuid else None
|
||||
if not profile:
|
||||
return HTTPFound(location=request.route_url('label_profiles'))
|
||||
|
||||
read_profile = HTTPFound(location=request.route_url(
|
||||
'label_profile.read', uuid=profile.uuid))
|
||||
|
||||
printer = profile.get_printer()
|
||||
if not printer:
|
||||
request.session.flash("Label profile \"%s\" does not have a functional "
|
||||
"printer spec." % profile)
|
||||
return read_profile
|
||||
if not printer.required_settings:
|
||||
request.session.flash("Printer class for label profile \"%s\" does not "
|
||||
"require any settings." % profile)
|
||||
return read_profile
|
||||
|
||||
if request.POST:
|
||||
for setting in printer.required_settings:
|
||||
if setting in request.POST:
|
||||
profile.save_printer_setting(setting, request.POST[setting])
|
||||
return read_profile
|
||||
|
||||
return {'profile': profile, 'printer': printer}
|
||||
|
||||
|
||||
def includeme(config):
|
||||
|
||||
config.add_route('label_profiles', '/labels/profiles')
|
||||
config.add_view(ProfilesGrid, route_name='label_profiles',
|
||||
renderer='/labels/profiles/index.mako',
|
||||
permission='label_profiles.list')
|
||||
|
||||
config.add_route('label_profile.create', '/labels/profiles/new')
|
||||
config.add_view(ProfileCrud, attr='create', route_name='label_profile.create',
|
||||
renderer='/labels/profiles/crud.mako',
|
||||
permission='label_profiles.create')
|
||||
|
||||
config.add_route('label_profile.read', '/labels/profiles/{uuid}')
|
||||
config.add_view(ProfileCrud, attr='read', route_name='label_profile.read',
|
||||
renderer='/labels/profiles/read.mako',
|
||||
permission='label_profiles.read')
|
||||
|
||||
config.add_route('label_profile.update', '/labels/profiles/{uuid}/edit')
|
||||
config.add_view(ProfileCrud, attr='update', route_name='label_profile.update',
|
||||
renderer='/labels/profiles/crud.mako',
|
||||
permission='label_profiles.update')
|
||||
|
||||
config.add_route('label_profile.delete', '/labels/profiles/{uuid}/delete')
|
||||
config.add_view(ProfileCrud, attr='delete', route_name='label_profile.delete',
|
||||
permission='label_profiles.delete')
|
||||
|
||||
config.add_route('label_profile.printer_settings', '/labels/profiles/{uuid}/printer')
|
||||
config.add_view(printer_settings, route_name='label_profile.printer_settings',
|
||||
renderer='/labels/profiles/printer.mako',
|
||||
permission='label_profiles.update')
|
|
@ -26,17 +26,27 @@
|
|||
``rattail.pyramid.views.products`` -- Product Views
|
||||
"""
|
||||
|
||||
import threading
|
||||
|
||||
from sqlalchemy import and_
|
||||
from sqlalchemy.orm import joinedload
|
||||
|
||||
from webhelpers.html.tags import link_to
|
||||
|
||||
from sqlalchemy.orm import joinedload
|
||||
from pyramid.httpexceptions import HTTPFound
|
||||
from pyramid.renderers import render_to_response
|
||||
|
||||
import edbob
|
||||
from edbob.pyramid import Session
|
||||
from edbob.pyramid.progress import SessionProgress
|
||||
from edbob.pyramid.views import SearchableAlchemyGridView, CrudView
|
||||
|
||||
import rattail
|
||||
import rattail.labels
|
||||
from rattail.pyramid.forms import UpcFieldRenderer, PriceFieldRenderer
|
||||
from rattail import sil
|
||||
from rattail import batches
|
||||
from rattail.exceptions import LabelPrintingError
|
||||
from rattail.pyramid.forms import GPCFieldRenderer, PriceFieldRenderer
|
||||
|
||||
|
||||
class ProductsGrid(SearchableAlchemyGridView):
|
||||
|
@ -47,6 +57,17 @@ class ProductsGrid(SearchableAlchemyGridView):
|
|||
clickable = True
|
||||
|
||||
def join_map(self):
|
||||
|
||||
def join_vendor(q):
|
||||
q = q.outerjoin(
|
||||
rattail.ProductCost,
|
||||
and_(
|
||||
rattail.ProductCost.product_uuid == rattail.Product.uuid,
|
||||
rattail.ProductCost.preference == 1,
|
||||
))
|
||||
q = q.outerjoin(rattail.Vendor)
|
||||
return q
|
||||
|
||||
return {
|
||||
'brand':
|
||||
lambda q: q.outerjoin(rattail.Brand),
|
||||
|
@ -62,6 +83,8 @@ class ProductsGrid(SearchableAlchemyGridView):
|
|||
'current_price':
|
||||
lambda q: q.outerjoin(rattail.ProductPrice,
|
||||
rattail.ProductPrice.uuid == rattail.Product.current_price_uuid),
|
||||
'vendor':
|
||||
join_vendor,
|
||||
}
|
||||
|
||||
def filter_map(self):
|
||||
|
@ -70,7 +93,8 @@ class ProductsGrid(SearchableAlchemyGridView):
|
|||
ilike=['description', 'size'],
|
||||
brand=self.filter_ilike(rattail.Brand.name),
|
||||
department=self.filter_ilike(rattail.Department.name),
|
||||
subdepartment=self.filter_ilike(rattail.Subdepartment.name))
|
||||
subdepartment=self.filter_ilike(rattail.Subdepartment.name),
|
||||
vendor=self.filter_ilike(rattail.Vendor.name))
|
||||
|
||||
def filter_config(self):
|
||||
return self.make_filter_config(
|
||||
|
@ -82,7 +106,9 @@ class ProductsGrid(SearchableAlchemyGridView):
|
|||
include_filter_description=True,
|
||||
filter_type_description='lk',
|
||||
include_filter_department=True,
|
||||
filter_type_department='lk')
|
||||
filter_type_department='lk',
|
||||
include_filter_vendor=True,
|
||||
filter_type_vendor='lk')
|
||||
|
||||
def sort_map(self):
|
||||
return self.make_sort_map(
|
||||
|
@ -91,7 +117,8 @@ class ProductsGrid(SearchableAlchemyGridView):
|
|||
department=self.sorter(rattail.Department.name),
|
||||
subdepartment=self.sorter(rattail.Subdepartment.name),
|
||||
regular_price=self.sorter(rattail.ProductPrice.price),
|
||||
current_price=self.sorter(rattail.ProductPrice.price))
|
||||
current_price=self.sorter(rattail.ProductPrice.price),
|
||||
vendor=self.sorter(rattail.Vendor.name))
|
||||
|
||||
def query(self):
|
||||
q = self.make_query()
|
||||
|
@ -100,11 +127,12 @@ class ProductsGrid(SearchableAlchemyGridView):
|
|||
q = q.options(joinedload(rattail.Product.subdepartment))
|
||||
q = q.options(joinedload(rattail.Product.regular_price))
|
||||
q = q.options(joinedload(rattail.Product.current_price))
|
||||
q = q.options(joinedload(rattail.Product.vendor))
|
||||
return q
|
||||
|
||||
def grid(self):
|
||||
g = self.make_grid()
|
||||
g.upc.set(renderer=UpcFieldRenderer)
|
||||
g.upc.set(renderer=GPCFieldRenderer)
|
||||
g.regular_price.set(renderer=PriceFieldRenderer)
|
||||
g.current_price.set(renderer=PriceFieldRenderer)
|
||||
g.configure(
|
||||
|
@ -114,6 +142,7 @@ class ProductsGrid(SearchableAlchemyGridView):
|
|||
g.description,
|
||||
g.size,
|
||||
g.subdepartment,
|
||||
g.vendor,
|
||||
g.regular_price.label("Reg. Price"),
|
||||
g.current_price.label("Cur. Price"),
|
||||
],
|
||||
|
@ -121,13 +150,19 @@ class ProductsGrid(SearchableAlchemyGridView):
|
|||
|
||||
g.click_route_name = 'product.read'
|
||||
|
||||
if edbob.config.getboolean('rattail.labels', 'enabled', default=False):
|
||||
q = Session.query(rattail.LabelProfile)
|
||||
if q.count():
|
||||
def labels(row):
|
||||
return link_to("Print", '#', class_='print-label')
|
||||
g.add_column('labels', "Labels", labels)
|
||||
|
||||
return g
|
||||
|
||||
def render_kwargs(self):
|
||||
q = Session.query(rattail.LabelProfile)
|
||||
q = q.order_by(rattail.LabelProfile.ordinal)
|
||||
return {'label_profiles': q.all()}
|
||||
|
||||
|
||||
class ProductCrud(CrudView):
|
||||
|
||||
|
@ -136,7 +171,7 @@ class ProductCrud(CrudView):
|
|||
|
||||
def fieldset(self, model):
|
||||
fs = self.make_fieldset(model)
|
||||
fs.upc.set(renderer=UpcFieldRenderer)
|
||||
fs.upc.set(renderer=GPCFieldRenderer)
|
||||
fs.regular_price.set(renderer=PriceFieldRenderer)
|
||||
fs.current_price.set(renderer=PriceFieldRenderer)
|
||||
fs.configure(
|
||||
|
@ -153,24 +188,90 @@ class ProductCrud(CrudView):
|
|||
return fs
|
||||
|
||||
|
||||
def print_label(request):
|
||||
def print_labels(request):
|
||||
profile = request.params.get('profile')
|
||||
profile = rattail.labels.get_profile(profile) if profile else None
|
||||
assert profile
|
||||
profile = Session.query(rattail.LabelProfile).get(profile) if profile else None
|
||||
if not profile:
|
||||
return {'error': "Label profile not found"}
|
||||
|
||||
uuid = request.params.get('uuid')
|
||||
product = Session.query(rattail.Product).get(uuid) if uuid else None
|
||||
assert product
|
||||
product = request.params.get('product')
|
||||
product = Session.query(rattail.Product).get(product) if product else None
|
||||
if not product:
|
||||
return {'error': "Product not found"}
|
||||
|
||||
quantity = request.params.get('quantity')
|
||||
assert quantity.isdigit()
|
||||
if not quantity.isdigit():
|
||||
return {'error': "Quantity must be numeric"}
|
||||
quantity = int(quantity)
|
||||
|
||||
printer = profile.get_printer()
|
||||
printer.print_labels([(product, quantity)])
|
||||
if not printer:
|
||||
return {'error': "Couldn't get printer from label profile"}
|
||||
|
||||
try:
|
||||
printer.print_labels([(product, quantity)])
|
||||
except LabelPrintingError, error:
|
||||
return {'error': str(error)}
|
||||
return {}
|
||||
|
||||
|
||||
class CreateProductsBatch(ProductsGrid):
|
||||
|
||||
def make_batch(self, provider):
|
||||
session = edbob.Session()
|
||||
|
||||
self._filter_config = self.filter_config()
|
||||
self._sort_config = self.sort_config()
|
||||
products = self.make_query(session)
|
||||
|
||||
progress = SessionProgress(self.request.session, 'products.batch')
|
||||
batch = provider.make_batch(session, products, progress)
|
||||
if not batch:
|
||||
session.rollback()
|
||||
session.close()
|
||||
return
|
||||
|
||||
session.commit()
|
||||
session.refresh(batch)
|
||||
session.close()
|
||||
|
||||
progress.session.load()
|
||||
progress.session['success_url'] = self.request.route_url('batch', uuid=batch.uuid)
|
||||
progress.session['success_msg'] = "Batch \"%s\" has been created." % batch.description
|
||||
progress.session.save()
|
||||
|
||||
def __call__(self):
|
||||
if self.request.POST:
|
||||
provider = self.request.POST.get('provider')
|
||||
if provider:
|
||||
provider = batches.get_provider(provider)
|
||||
if provider:
|
||||
|
||||
if self.request.POST.get('params') == 'True':
|
||||
provider.set_params(Session(), **self.request.POST)
|
||||
|
||||
else:
|
||||
try:
|
||||
url = self.request.route_url('batch_params.%s' % provider.name)
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
self.request.session['referer'] = self.request.current_route_url()
|
||||
return HTTPFound(location=url)
|
||||
|
||||
thread = threading.Thread(target=self.make_batch, args=(provider,))
|
||||
thread.start()
|
||||
kwargs = {
|
||||
'key': 'products.batch',
|
||||
'cancel_url': self.request.route_url('products'),
|
||||
'cancel_msg': "Batch creation was cancelled.",
|
||||
}
|
||||
return render_to_response('/progress.mako', kwargs, request=self.request)
|
||||
|
||||
providers = [(x.name, x.description) for x in batches.iter_providers()]
|
||||
return {'providers': providers}
|
||||
|
||||
|
||||
def includeme(config):
|
||||
|
||||
config.add_route('products', '/products')
|
||||
|
@ -178,158 +279,16 @@ def includeme(config):
|
|||
renderer='/products/index.mako',
|
||||
permission='products.list')
|
||||
|
||||
config.add_route('products.print_label', '/products/label')
|
||||
config.add_view(print_label, route_name='products.print_label',
|
||||
renderer='json')
|
||||
config.add_route('products.print_labels', '/products/labels')
|
||||
config.add_view(print_labels, route_name='products.print_labels',
|
||||
renderer='json', permission='products.print_labels')
|
||||
|
||||
config.add_route('products.create_batch', '/products/batch')
|
||||
config.add_view(CreateProductsBatch, route_name='products.create_batch',
|
||||
renderer='/products/batch.mako',
|
||||
permission='batches.create')
|
||||
|
||||
config.add_route('product.read', '/products/{uuid}')
|
||||
config.add_view(ProductCrud, attr='read', route_name='product.read',
|
||||
renderer='/products/read.mako',
|
||||
permission='products.read')
|
||||
|
||||
|
||||
# from sqlalchemy.orm import joinedload
|
||||
|
||||
# import transaction
|
||||
# from pyramid.httpexceptions import HTTPFound
|
||||
# from pyramid.view import view_config
|
||||
|
||||
# from edbob.pyramid import filters
|
||||
# from edbob.pyramid import forms
|
||||
# from edbob.pyramid import grids
|
||||
# from edbob.pyramid import Session
|
||||
|
||||
# import rattail
|
||||
# from rattail.batches import next_batch_id
|
||||
# from rattail.pyramid import util
|
||||
# from rattail.pyramid.forms import UpcFieldRenderer
|
||||
|
||||
|
||||
# def filter_map():
|
||||
# return filters.get_filter_map(
|
||||
# rattail.Product,
|
||||
# exact=['upc'],
|
||||
# ilike=['description', 'size'],
|
||||
# department=filters.filter_ilike(rattail.Department.name),
|
||||
# brand=filters.filter_ilike(rattail.Brand.name))
|
||||
|
||||
# def search_config(request, fmap):
|
||||
# return filters.get_search_config(
|
||||
# 'products.list', request, fmap,
|
||||
# include_filter_brand=True,
|
||||
# filter_type_brand='lk',
|
||||
# include_filter_description=True,
|
||||
# filter_type_description='lk',
|
||||
# include_filter_department=True,
|
||||
# filter_type_department='lk')
|
||||
|
||||
# def search_form(config):
|
||||
# return filters.get_search_form(
|
||||
# config, upc="UPC")
|
||||
|
||||
# def grid_config(request, search, fmap):
|
||||
# return grids.get_grid_config(
|
||||
# 'products.list', request, search,
|
||||
# filter_map=fmap, sort='description')
|
||||
|
||||
# def sort_map():
|
||||
# return grids.get_sort_map(
|
||||
# rattail.Product,
|
||||
# ['upc', 'description', 'size'],
|
||||
# department=grids.sorter(rattail.Department.name),
|
||||
# brand=grids.sorter(rattail.Brand.name))
|
||||
|
||||
# def query(config):
|
||||
# jmap = {
|
||||
# 'department': lambda q: q.outerjoin(rattail.Department),
|
||||
# 'brand': lambda q: q.outerjoin(rattail.Brand),
|
||||
# }
|
||||
# smap = sort_map()
|
||||
# q = Session.query(rattail.Product)
|
||||
# q = q.options(joinedload(rattail.Product.department))
|
||||
# q = q.options(joinedload(rattail.Product.brand))
|
||||
# q = filters.filter_query(q, config, jmap)
|
||||
# q = grids.sort_query(q, config, smap, jmap)
|
||||
# return q
|
||||
|
||||
|
||||
# @view_config(route_name='products.list', renderer='/products/index.mako')
|
||||
# def products(context, request):
|
||||
|
||||
# fmap = filter_map()
|
||||
# config = search_config(request, fmap)
|
||||
# search = search_form(config)
|
||||
# config = grid_config(request, search, fmap)
|
||||
# products = grids.get_pager(query, config)
|
||||
|
||||
# g = forms.AlchemyGrid(
|
||||
# rattail.Product, products, config,
|
||||
# gridurl=request.route_url('products.list'))
|
||||
|
||||
# g.configure(
|
||||
# include=[
|
||||
# g.upc.with_renderer(UpcFieldRenderer).label("UPC"),
|
||||
# g.brand,
|
||||
# g.description,
|
||||
# g.size,
|
||||
# g.department,
|
||||
# ],
|
||||
# readonly=True)
|
||||
|
||||
# grid = g.render(class_='clickable products')
|
||||
# return grids.render_grid(request, grid, search)
|
||||
|
||||
|
||||
# @view_config(route_name='products.batch')
|
||||
# def batch(context, request):
|
||||
|
||||
# fmap = filter_map()
|
||||
# config = search_config(request, fmap)
|
||||
# search = search_form(config)
|
||||
# config = grid_config(request, search, fmap)
|
||||
# products = query(config)
|
||||
|
||||
# home = HTTPFound(location=request.route_url('products.list'))
|
||||
|
||||
# source = util.get_terminal('rattail')
|
||||
# if not source:
|
||||
# return home
|
||||
|
||||
# dct = util.get_dictionary('ITEM_DCT')
|
||||
# if not dct:
|
||||
# return home
|
||||
|
||||
# with transaction.manager:
|
||||
# batch = rattail.Batch()
|
||||
# Session.add(batch)
|
||||
|
||||
# batch.source = source
|
||||
# batch.source_description = source.description
|
||||
# batch.batch_id = next_batch_id(source.sil_id, consume=True,
|
||||
# session=Session())
|
||||
# batch.name = '%s.%08u' % (source.sil_id, batch.batch_id)
|
||||
# batch.dictionary = dct
|
||||
# batch.action_type = rattail.BATCH_ADD
|
||||
# batch.description = "products from Rattail"
|
||||
|
||||
# for i, col in enumerate(source.source_columns(dct), 1):
|
||||
# batch.columns.append(rattail.BatchColumn(
|
||||
# ordinal=i,
|
||||
# sil_column=col.sil_column,
|
||||
# source=source,
|
||||
# targeted=True,
|
||||
# ))
|
||||
|
||||
# batch.create_table()
|
||||
# batch.add_rows(source, dct, query=products)
|
||||
# batch.rowcount = products.count()
|
||||
|
||||
# url = request.route_url('batch.edit', uuid=batch.uuid)
|
||||
|
||||
# return HTTPFound(location=url)
|
||||
|
||||
|
||||
# def includeme(config):
|
||||
# config.add_route('products.list', '/products')
|
||||
# config.add_route('products.batch', '/products/batch')
|
||||
# config.scan(__name__)
|
||||
|
|
Loading…
Reference in a new issue