more batch improvements (save point)
This commit is contained in:
parent
523d7de3e7
commit
675c4deb63
|
@ -5,8 +5,9 @@
|
||||||
|
|
||||||
<%def name="menu()">
|
<%def name="menu()">
|
||||||
<p>${h.link_to("Back to Batches", url('batch.list'))}</p>
|
<p>${h.link_to("Back to Batches", url('batch.list'))}</p>
|
||||||
% if fieldset.edit and fieldset.model.rowcount:
|
% if fieldset.edit:
|
||||||
<p>${h.link_to("View Batch Details", url('batch.details', uuid=fieldset.model.uuid))}</p>
|
<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
|
% endif
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<%def name="title()">Batch Dictionaries</%def>
|
<%def name="title()">Batch Dictionaries</%def>
|
||||||
|
|
||||||
<%def name="menu()">
|
<%def name="menu()">
|
||||||
<p>${h.link_to("Back to Batches", url('batches'))}</p>
|
<p>${h.link_to("Back to Batches", url('batch.list'))}</p>
|
||||||
## <p>${h.link_to("Create a New Dictionary", url('batch_dictionary'))}</p>
|
## <p>${h.link_to("Create a New Dictionary", url('batch_dictionary'))}</p>
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,8 @@
|
||||||
<%inherit file="/crud.mako" />
|
<%inherit file="/crud.mako" />
|
||||||
|
|
||||||
<%def name="menu()">
|
<%def name="menu()">
|
||||||
<p>${h.link_to("Back to Batches", url('batches'))}</p>
|
<p>${h.link_to("Back to Batches", url('batch.list'))}</p>
|
||||||
<p>${h.link_to("Back to Dictionaries", url('batch_dictionaries'))}</p>
|
<p>${h.link_to("Back to Dictionaries", url('batch_dictionaries'))}</p>
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
${parent.body()}
|
${parent.body()}
|
||||||
|
|
||||||
${columns|n}
|
|
||||||
|
|
|
@ -3,9 +3,34 @@
|
||||||
|
|
||||||
<%def name="title()">Batches</%def>
|
<%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()">
|
<%def name="menu()">
|
||||||
## <p>${h.link_to("Create a New Batch", url('batch.new'))}</p>
|
## <p>${h.link_to("Create a New Batch", url('batch.new'))}</p>
|
||||||
<p>${h.link_to("Manage Terminals", url('batch_terminal.list'))}</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("View Dictionaries", url('batch_dictionaries'))}</p>
|
||||||
<p>${h.link_to("SIL Columns", url('sil_columns'))}</p>
|
<p>${h.link_to("SIL Columns", url('sil_columns'))}</p>
|
||||||
</%def>
|
</%def>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<%inherit file="/crud.mako" />
|
<%inherit file="/crud.mako" />
|
||||||
|
|
||||||
<%def name="menu()">
|
<%def name="menu()">
|
||||||
<p>${h.link_to("Back to Batches", url('batches'))}</p>
|
<p>${h.link_to("Back to Batches", url('batch.list'))}</p>
|
||||||
<p>${h.link_to("Back to SIL Columns", url('sil_columns'))}</p>
|
<p>${h.link_to("Back to SIL Columns", url('sil_columns'))}</p>
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<%def name="title()">SIL Columns</%def>
|
<%def name="title()">SIL Columns</%def>
|
||||||
|
|
||||||
<%def name="menu()">
|
<%def name="menu()">
|
||||||
<p>${h.link_to("Back to Batches", url('batches'))}</p>
|
<p>${h.link_to("Back to Batches", url('batch.list'))}</p>
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
${parent.body()}
|
${parent.body()}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
<%def name="menu()">
|
<%def name="menu()">
|
||||||
<p>${h.link_to("Back to Batches", url('batch.list'))}</p>
|
<p>${h.link_to("Back to Batches", url('batch.list'))}</p>
|
||||||
<p>${h.link_to("Back to Batch Terminals", url('batch_terminal.list'))}</p>
|
<p>${h.link_to("Back to Batch Terminals", url('batch_terminals'))}</p>
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
${parent.body()}
|
${parent.body()}
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
<%inherit file="/products/base.mako" />
|
<%inherit file="/products/base.mako" />
|
||||||
<%inherit file="/index.mako" />
|
<%inherit file="/index.mako" />
|
||||||
|
|
||||||
<%def name="title()">Products</%def>
|
|
||||||
|
|
||||||
<%def name="menu()">
|
<%def name="menu()">
|
||||||
|
<p>${h.link_to("New Batch from Results", url('products.batch'))}</p>
|
||||||
</%def>
|
</%def>
|
||||||
|
<%def name="title()">Products</%def>
|
||||||
${parent.body()}
|
${parent.body()}
|
||||||
|
|
96
rattail/pyramid/util.py
Normal file
96
rattail/pyramid/util.py
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
#!/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))
|
|
@ -47,6 +47,7 @@ from edbob.util import prettify
|
||||||
import rattail
|
import rattail
|
||||||
from rattail import sil
|
from rattail import sil
|
||||||
from rattail.batches import next_batch_id
|
from rattail.batches import next_batch_id
|
||||||
|
from rattail.pyramid import util
|
||||||
from rattail.pyramid.forms import (
|
from rattail.pyramid.forms import (
|
||||||
BatchIdFieldRenderer,
|
BatchIdFieldRenderer,
|
||||||
unique_batch_terminal_id,
|
unique_batch_terminal_id,
|
||||||
|
@ -91,9 +92,8 @@ def sil_columns(context, request):
|
||||||
columns = grids.get_pager(query, config)
|
columns = grids.get_pager(query, config)
|
||||||
g = forms.AlchemyGrid(
|
g = forms.AlchemyGrid(
|
||||||
rattail.SilColumn, columns, config,
|
rattail.SilColumn, columns, config,
|
||||||
request.route_url('sil_columns'),
|
gridurl=request.route_url('sil_columns'),
|
||||||
url_object=request.route_url('sil_column'),
|
objurl='sil_column', delurl='sil_column')
|
||||||
url_delete=request.route_url('sil_column'))
|
|
||||||
|
|
||||||
g.configure(
|
g.configure(
|
||||||
include=[
|
include=[
|
||||||
|
@ -171,9 +171,8 @@ def batch_dictionaries(context, request):
|
||||||
dictionaries = grids.get_pager(query, config)
|
dictionaries = grids.get_pager(query, config)
|
||||||
g = forms.AlchemyGrid(
|
g = forms.AlchemyGrid(
|
||||||
rattail.BatchDictionary, dictionaries, config,
|
rattail.BatchDictionary, dictionaries, config,
|
||||||
request.route_url('batch_dictionaries'),
|
gridurl=request.route_url('batch_dictionaries'),
|
||||||
url_object=request.route_url('batch_dictionary'),
|
objurl='batch_dictionary', delurl='batch_dictionary')
|
||||||
url_delete=request.route_url('batch_dictionary'))
|
|
||||||
|
|
||||||
g.configure(
|
g.configure(
|
||||||
include=[
|
include=[
|
||||||
|
@ -302,7 +301,6 @@ def _terminal_columns(request, terminal):
|
||||||
|
|
||||||
def query(config):
|
def query(config):
|
||||||
q = Session.query(rattail.BatchTerminalColumn)
|
q = Session.query(rattail.BatchTerminalColumn)
|
||||||
# q = q.join(rattail.BatchDictionary)
|
|
||||||
q = q.options(joinedload(rattail.BatchTerminalColumn.dictionary))
|
q = q.options(joinedload(rattail.BatchTerminalColumn.dictionary))
|
||||||
q = q.options(joinedload(rattail.BatchTerminalColumn.sil_column))
|
q = q.options(joinedload(rattail.BatchTerminalColumn.sil_column))
|
||||||
q = q.filter(rattail.BatchTerminalColumn.terminal_uuid == terminal.uuid)
|
q = q.filter(rattail.BatchTerminalColumn.terminal_uuid == terminal.uuid)
|
||||||
|
@ -343,78 +341,63 @@ def terminal_columns(context, request):
|
||||||
|
|
||||||
def update_terminal_info(terminal):
|
def update_terminal_info(terminal):
|
||||||
"""
|
"""
|
||||||
Updates the terminal's list of supported source and target columns, based
|
This function updates a :class:`rattail.BatchTerminal` instance to reflect
|
||||||
on feedback from the actual :class:`rattail.batch.BatchTerminal` instance.
|
the reality found by way of inspecting its underlying
|
||||||
Also sets the terminal's ``functional`` flag (et al.) to reflect reality.
|
:class:`rattail.batches.BatchTerminal` instance.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
terminal.functional = True
|
# Assume the worst.
|
||||||
|
terminal.functional = False
|
||||||
|
del terminal.columns[:]
|
||||||
|
|
||||||
|
# Fetch "real" terminal instance, if we can.
|
||||||
try:
|
try:
|
||||||
true_terminal = terminal.get_terminal()
|
true_terminal = terminal.get_terminal()
|
||||||
except LoadSpecError, err:
|
except LoadSpecError, err:
|
||||||
terminal.functional = False
|
|
||||||
return err
|
return err
|
||||||
else:
|
|
||||||
if true_terminal:
|
|
||||||
# for column_type in ('source', 'target'):
|
|
||||||
# declared_columns = getattr(true_terminal, '%s_columns' % column_type)
|
|
||||||
# stored_columns = getattr(terminal, '%s_columns' % column_type)
|
|
||||||
# cls = getattr(rattail, 'BatchTerminal%sColumn' % column_type.title())
|
|
||||||
# for dictionary, columns in declared_columns.iteritems():
|
|
||||||
# q = Session.query(rattail.BatchDictionary)
|
|
||||||
# q = q.filter_by(name=dictionary)
|
|
||||||
# dictionary = q.one()
|
|
||||||
# for col in columns:
|
|
||||||
# q = Session.query(rattail.SilColumn)
|
|
||||||
# q = q.filter_by(sil_name=col)
|
|
||||||
# col = q.one()
|
|
||||||
# stored_columns.append(cls(
|
|
||||||
# dictionary=dictionary,
|
|
||||||
# column=col))
|
|
||||||
# setattr(terminal, column_type, bool(declared_columns))
|
|
||||||
stored_columns = {}
|
|
||||||
for col in terminal.columns:
|
|
||||||
stored_columns[col.sil_column.sil_name] = col
|
|
||||||
for column_type in ('source', 'target'):
|
|
||||||
declared_columns = getattr(true_terminal, '%s_columns' % column_type)
|
|
||||||
for dictionary, columns in declared_columns.iteritems():
|
|
||||||
q = Session.query(rattail.BatchDictionary)
|
|
||||||
q = q.filter_by(name=dictionary)
|
|
||||||
dictionary = q.one()
|
|
||||||
for col in columns:
|
|
||||||
q = Session.query(rattail.SilColumn)
|
|
||||||
q = q.filter_by(sil_name=col)
|
|
||||||
col = q.one()
|
|
||||||
if col.sil_name in stored_columns:
|
|
||||||
setattr(stored_columns[col.sil_name], column_type, True)
|
|
||||||
else:
|
|
||||||
col = rattail.BatchTerminalColumn(
|
|
||||||
dictionary=dictionary,
|
|
||||||
sil_column=col)
|
|
||||||
setattr(col, column_type, True)
|
|
||||||
terminal.columns.append(col)
|
|
||||||
stored_columns[col.sil_column.sil_name] = col
|
|
||||||
# Session.add(col)
|
|
||||||
Session.flush()
|
|
||||||
# stored_columns.append(rattail.BatchTerminalColumn(
|
|
||||||
# dictionary=dictionary,
|
|
||||||
# sil_column=col))
|
|
||||||
setattr(terminal, column_type, bool(declared_columns))
|
|
||||||
for col in terminal.columns:
|
|
||||||
if not col.source:
|
|
||||||
col.source = False
|
|
||||||
if not col.target:
|
|
||||||
col.target = False
|
|
||||||
return true_terminal
|
|
||||||
else:
|
|
||||||
terminal.functional = False
|
|
||||||
|
|
||||||
|
# Spec was fine but still no terminal? (This may not be needed?)
|
||||||
|
if not true_terminal:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Okay, we have *something*.
|
||||||
|
terminal.functional = True
|
||||||
|
|
||||||
|
if true_terminal.source_columns:
|
||||||
|
terminal.source = True
|
||||||
|
for dct, cols in true_terminal.source_columns.iteritems():
|
||||||
|
dct = util.get_dictionary(dct)
|
||||||
|
for col in cols:
|
||||||
|
col = rattail.BatchTerminalColumn(
|
||||||
|
dictionary=dct,
|
||||||
|
sil_column=util.get_column(col),
|
||||||
|
source=True,
|
||||||
|
target=False)
|
||||||
|
terminal.columns.append(col)
|
||||||
|
Session.flush()
|
||||||
|
|
||||||
|
if true_terminal.target_columns:
|
||||||
|
terminal.target = True
|
||||||
|
for dct, cols in true_terminal.target_columns.iteritems():
|
||||||
|
dct = util.get_dictionary(dct)
|
||||||
|
for col in cols:
|
||||||
|
col = rattail.BatchTerminalColumn(
|
||||||
|
dictionary=dct,
|
||||||
|
sil_column=util.get_column(col),
|
||||||
|
source=False,
|
||||||
|
target=True)
|
||||||
|
terminal.columns.append(col)
|
||||||
|
Session.flush()
|
||||||
|
|
||||||
|
# Really, why?
|
||||||
|
return true_terminal
|
||||||
|
|
||||||
|
|
||||||
def terminal_fieldset(terminal, request):
|
def terminal_fieldset(terminal, request):
|
||||||
fs = forms.make_fieldset(
|
fs = forms.make_fieldset(
|
||||||
terminal, crud_title="Batch Terminal",
|
terminal, crud_title="Batch Terminal",
|
||||||
url_action=request.current_route_url(),
|
url_action=request.current_route_url(),
|
||||||
url_cancel=request.route_url('batch_terminal.list'))
|
url_cancel=request.route_url('batch_terminals'))
|
||||||
|
|
||||||
fs.configure(
|
fs.configure(
|
||||||
include=[
|
include=[
|
||||||
|
@ -422,13 +405,11 @@ def terminal_fieldset(terminal, request):
|
||||||
fs.description,
|
fs.description,
|
||||||
fs.class_spec.validate(forms.required),
|
fs.class_spec.validate(forms.required),
|
||||||
fs.functional.readonly(),
|
fs.functional.readonly(),
|
||||||
# fs.source_kwargs,
|
|
||||||
# fs.target_kwargs,
|
|
||||||
])
|
])
|
||||||
|
|
||||||
# if not fs.edit:
|
if not fs.edit:
|
||||||
# del fs.source_kwargs
|
del fs.functional
|
||||||
# del fs.target_kwargs
|
|
||||||
return fs
|
return fs
|
||||||
|
|
||||||
|
|
||||||
|
@ -508,7 +489,7 @@ def delete_terminal(context, request):
|
||||||
assert terminal
|
assert terminal
|
||||||
with transaction.manager:
|
with transaction.manager:
|
||||||
Session.delete(terminal)
|
Session.delete(terminal)
|
||||||
return HTTPFound(location=request.route_url('batch_terminal.list'))
|
return HTTPFound(location=request.route_url('batch_terminals'))
|
||||||
|
|
||||||
|
|
||||||
# @view_config(route_name='batch_terminal', renderer='/batches/terminal.mako')
|
# @view_config(route_name='batch_terminal', renderer='/batches/terminal.mako')
|
||||||
|
@ -563,7 +544,7 @@ def delete_terminal(context, request):
|
||||||
# pre_render=pre_render, post_sync=post_sync)
|
# pre_render=pre_render, post_sync=post_sync)
|
||||||
|
|
||||||
|
|
||||||
@view_config(route_name='batch_terminal.list', renderer='/batches/terminals.mako')
|
@view_config(route_name='batch_terminals', renderer='/batches/terminals.mako')
|
||||||
def terminals(context, request):
|
def terminals(context, request):
|
||||||
|
|
||||||
fmap = filters.get_filter_map(
|
fmap = filters.get_filter_map(
|
||||||
|
@ -572,7 +553,7 @@ def terminals(context, request):
|
||||||
ilike=['description'])
|
ilike=['description'])
|
||||||
|
|
||||||
config = filters.get_search_config(
|
config = filters.get_search_config(
|
||||||
'batch_terminal.list', request, fmap,
|
'batch_terminals', request, fmap,
|
||||||
include_filter_description=True,
|
include_filter_description=True,
|
||||||
filter_type_description='lk')
|
filter_type_description='lk')
|
||||||
|
|
||||||
|
@ -580,7 +561,7 @@ def terminals(context, request):
|
||||||
config, sil_id="SIL ID")
|
config, sil_id="SIL ID")
|
||||||
|
|
||||||
config = grids.get_grid_config(
|
config = grids.get_grid_config(
|
||||||
'batch_terminal.list', request, search,
|
'batch_terminals', request, search,
|
||||||
filter_map=fmap, sort='description', deletable=True)
|
filter_map=fmap, sort='description', deletable=True)
|
||||||
|
|
||||||
smap = grids.get_sort_map(
|
smap = grids.get_sort_map(
|
||||||
|
@ -596,7 +577,7 @@ def terminals(context, request):
|
||||||
terminals = grids.get_pager(query, config)
|
terminals = grids.get_pager(query, config)
|
||||||
g = forms.AlchemyGrid(
|
g = forms.AlchemyGrid(
|
||||||
rattail.BatchTerminal, terminals, config,
|
rattail.BatchTerminal, terminals, config,
|
||||||
gridurl=request.route_url('batch_terminal.list'),
|
gridurl=request.route_url('batch_terminals'),
|
||||||
objurl='batch_terminal.edit',
|
objurl='batch_terminal.edit',
|
||||||
delurl='batch_terminal.delete')
|
delurl='batch_terminal.delete')
|
||||||
|
|
||||||
|
@ -633,12 +614,14 @@ def batches(context, request):
|
||||||
|
|
||||||
config = grids.get_grid_config(
|
config = grids.get_grid_config(
|
||||||
'batches', request, search,
|
'batches', request, search,
|
||||||
filter_map=fmap, deletable=True, sort='target')
|
filter_map=fmap, deletable=True, sort='target',
|
||||||
|
actions=['Execute'])
|
||||||
|
|
||||||
smap = grids.get_sort_map(
|
smap = grids.get_sort_map(
|
||||||
rattail.Batch,
|
rattail.Batch,
|
||||||
['source_description', 'batch_id', 'action_type',
|
['source_description', 'batch_id', 'action_type',
|
||||||
'description', 'rowcount', 'effective'],
|
# 'description', 'rowcount', 'effective'],
|
||||||
|
'description', 'rowcount'],
|
||||||
target=grids.sorter(rattail.BatchTerminal.description))
|
target=grids.sorter(rattail.BatchTerminal.description))
|
||||||
|
|
||||||
def query(config):
|
def query(config):
|
||||||
|
@ -672,7 +655,7 @@ def batches(context, request):
|
||||||
g.action_type.with_renderer(forms.EnumFieldRenderer(rattail.BATCH_ACTION_TYPE)).label("Action"),
|
g.action_type.with_renderer(forms.EnumFieldRenderer(rattail.BATCH_ACTION_TYPE)).label("Action"),
|
||||||
g.description,
|
g.description,
|
||||||
g.rowcount.label("Rows"),
|
g.rowcount.label("Rows"),
|
||||||
g.effective.with_renderer(forms.PrettyDateTimeFieldRenderer),
|
# g.effective.with_renderer(forms.PrettyDateTimeFieldRenderer),
|
||||||
])
|
])
|
||||||
|
|
||||||
g.readonly = True
|
g.readonly = True
|
||||||
|
@ -692,7 +675,7 @@ def _batch_columns(request, batch):
|
||||||
smap = grids.get_sort_map(
|
smap = grids.get_sort_map(
|
||||||
rattail.BatchColumn,
|
rattail.BatchColumn,
|
||||||
['ordinal', 'targeted'])
|
['ordinal', 'targeted'])
|
||||||
smap['column'] = grids.sorter(rattail.SilColumn.sil_name)
|
smap['sil_column'] = grids.sorter(rattail.SilColumn.sil_name)
|
||||||
smap['display'] = grids.sorter(rattail.SilColumn.display)
|
smap['display'] = grids.sorter(rattail.SilColumn.display)
|
||||||
smap['source'] = grids.sorter(rattail.BatchTerminal.description)
|
smap['source'] = grids.sorter(rattail.BatchTerminal.description)
|
||||||
|
|
||||||
|
@ -741,10 +724,7 @@ def batch_fieldset(batch, request):
|
||||||
|
|
||||||
# Remove unsupported action types...for now.
|
# Remove unsupported action types...for now.
|
||||||
enum = rattail.BATCH_ACTION_TYPE.copy()
|
enum = rattail.BATCH_ACTION_TYPE.copy()
|
||||||
del enum[rattail.BATCH_ADD_REPLACE]
|
|
||||||
del enum[rattail.BATCH_CHANGE]
|
|
||||||
del enum[rattail.BATCH_LOAD]
|
del enum[rattail.BATCH_LOAD]
|
||||||
del enum[rattail.BATCH_REMOVE]
|
|
||||||
|
|
||||||
fs.configure(
|
fs.configure(
|
||||||
include=[
|
include=[
|
||||||
|
@ -754,20 +734,21 @@ def batch_fieldset(batch, request):
|
||||||
fs.dictionary.validate(forms.required),
|
fs.dictionary.validate(forms.required),
|
||||||
fs.action_type.with_renderer(forms.EnumFieldRenderer(enum)).validate(forms.required).label("Action"),
|
fs.action_type.with_renderer(forms.EnumFieldRenderer(enum)).validate(forms.required).label("Action"),
|
||||||
fs.description,
|
fs.description,
|
||||||
fs.effective.with_renderer(forms.PrettyDateTimeFieldRenderer),
|
# fs.effective.with_renderer(forms.PrettyDateTimeFieldRenderer),
|
||||||
fs.rowcount.label("Rows").readonly(),
|
fs.rowcount.label("Rows").readonly(),
|
||||||
])
|
])
|
||||||
|
|
||||||
if fs.edit:
|
if fs.edit:
|
||||||
fs.source.set(readonly=True)
|
fs.source.set(readonly=True)
|
||||||
fs.dictionary.set(readonly=True)
|
fs.dictionary.set(readonly=True)
|
||||||
if fs.model.target:
|
# if fs.model.target:
|
||||||
fs.target.set(readonly=True)
|
# fs.target.set(readonly=True)
|
||||||
fs.action_type.set(readonly=True)
|
# fs.action_type.set(readonly=True)
|
||||||
fs.effective.set(readonly=True)
|
# fs.effective.set(readonly=True)
|
||||||
fs.append(forms.ChildGridField('columns', _batch_columns(request, fs.model)))
|
fs.append(forms.ChildGridField('columns', _batch_columns(request, fs.model)))
|
||||||
else:
|
else:
|
||||||
del fs.batch_id
|
del fs.batch_id
|
||||||
del fs.effective
|
# del fs.effective
|
||||||
del fs.rowcount
|
del fs.rowcount
|
||||||
return fs
|
return fs
|
||||||
|
|
||||||
|
@ -995,38 +976,13 @@ def execute(context, request):
|
||||||
Executes a batch.
|
Executes a batch.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
home = HTTPFound(location=request.route_url('batch.list'))
|
|
||||||
|
|
||||||
# batch = self.request.params.get('uuid')
|
|
||||||
# batch = self.Session.query(rattail.Batch).get(batch) if batch else None
|
|
||||||
# if not batch:
|
|
||||||
# return home
|
|
||||||
# print 'got a batch'
|
|
||||||
|
|
||||||
uuid = request.matchdict['uuid']
|
uuid = request.matchdict['uuid']
|
||||||
|
home = HTTPFound(location=request.route_url('batch.list'))
|
||||||
|
|
||||||
with transaction.manager:
|
with transaction.manager:
|
||||||
batch = Session.query(rattail.Batch).get(uuid) if uuid else None
|
batch = Session.query(rattail.Batch).get(uuid) if uuid else None
|
||||||
if not batch:
|
if not batch:
|
||||||
return home
|
return home
|
||||||
# print 'got a batch'
|
|
||||||
|
|
||||||
# jct = batch.target_junction
|
|
||||||
# if not jct:
|
|
||||||
# self.request.session.flash("Batch does not have a valid target")
|
|
||||||
# return home
|
|
||||||
# print 'got a target'
|
|
||||||
|
|
||||||
# if not batch.target:
|
|
||||||
# request.session.flash("Batch does not have a valid target")
|
|
||||||
# return home
|
|
||||||
|
|
||||||
# jct = jct()
|
|
||||||
# if batch.dictionary == rattail.BATCH_MAIN_ITEM:
|
|
||||||
# print 'exporting main item'
|
|
||||||
# jct.export_main_item(batch, self.Session)
|
|
||||||
# print 'exported main item'
|
|
||||||
|
|
||||||
batch.execute()
|
batch.execute()
|
||||||
|
|
||||||
# table = batch.table
|
# table = batch.table
|
||||||
|
@ -1053,10 +1009,10 @@ def includeme(config):
|
||||||
config.add_route('batch_dictionary', '/batches/dictionary')
|
config.add_route('batch_dictionary', '/batches/dictionary')
|
||||||
config.add_route('batch_dictionary.columns', '/batches/dictionary-columns')
|
config.add_route('batch_dictionary.columns', '/batches/dictionary-columns')
|
||||||
|
|
||||||
config.add_route('batch_terminal.list', '/batches/terminals')
|
config.add_route('batch_terminals', '/batches/terminals')
|
||||||
config.add_route('batch_terminal.new', '/batches/terminal')
|
config.add_route('batch_terminal.new', '/batches/terminal/new')
|
||||||
config.add_route('batch_terminal.delete', '/batches/terminal/{uuid}/delete')
|
|
||||||
config.add_route('batch_terminal.edit', '/batches/terminal/{uuid}/edit')
|
config.add_route('batch_terminal.edit', '/batches/terminal/{uuid}/edit')
|
||||||
|
config.add_route('batch_terminal.delete', '/batches/terminal/{uuid}/delete')
|
||||||
config.add_route('batch_terminal.columns', '/batches/terminal/{uuid}/columns')
|
config.add_route('batch_terminal.columns', '/batches/terminal/{uuid}/columns')
|
||||||
# config.add_route('batch_terminal', '/batches/terminal/{uuid}')
|
# config.add_route('batch_terminal', '/batches/terminal/{uuid}')
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
``rattail.pyramid.views.departments`` -- Department Views
|
``rattail.pyramid.views.departments`` -- Department Views
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import transaction
|
||||||
|
from pyramid.httpexceptions import HTTPFound
|
||||||
from pyramid.view import view_config
|
from pyramid.view import view_config
|
||||||
|
|
||||||
from edbob.pyramid import filters
|
from edbob.pyramid import filters
|
||||||
|
@ -36,7 +38,7 @@ from edbob.pyramid import Session
|
||||||
import rattail
|
import rattail
|
||||||
|
|
||||||
|
|
||||||
@view_config(route_name='department.list', renderer='/departments/index.mako')
|
@view_config(route_name='departments.list', renderer='/departments/index.mako')
|
||||||
def list_departments(context, request):
|
def list_departments(context, request):
|
||||||
|
|
||||||
fmap = filters.get_filter_map(
|
fmap = filters.get_filter_map(
|
||||||
|
@ -45,15 +47,15 @@ def list_departments(context, request):
|
||||||
ilike=['name'])
|
ilike=['name'])
|
||||||
|
|
||||||
config = filters.get_search_config(
|
config = filters.get_search_config(
|
||||||
'department.list', request, fmap,
|
'departments.list', request, fmap,
|
||||||
include_filter_name=True,
|
include_filter_name=True,
|
||||||
filter_type_name='lk')
|
filter_type_name='lk')
|
||||||
|
|
||||||
search = filters.get_search_form(config)
|
search = filters.get_search_form(config)
|
||||||
|
|
||||||
config = grids.get_grid_config(
|
config = grids.get_grid_config(
|
||||||
'department.list', request, search,
|
'departments.list', request, search,
|
||||||
filter_map=fmap, sort='name')
|
filter_map=fmap, sort='name', deletable=True)
|
||||||
|
|
||||||
smap = grids.get_sort_map(
|
smap = grids.get_sort_map(
|
||||||
rattail.Department,
|
rattail.Department,
|
||||||
|
@ -68,7 +70,9 @@ def list_departments(context, request):
|
||||||
departments = grids.get_pager(query, config)
|
departments = grids.get_pager(query, config)
|
||||||
g = forms.AlchemyGrid(
|
g = forms.AlchemyGrid(
|
||||||
rattail.Department, departments, config,
|
rattail.Department, departments, config,
|
||||||
gridurl=request.route_url('department.list'))
|
gridurl=request.route_url('departments.list'),
|
||||||
|
delurl='department.delete',
|
||||||
|
)
|
||||||
|
|
||||||
g.configure(
|
g.configure(
|
||||||
include=[
|
include=[
|
||||||
|
@ -77,10 +81,25 @@ def list_departments(context, request):
|
||||||
],
|
],
|
||||||
readonly=True)
|
readonly=True)
|
||||||
|
|
||||||
grid = g.render(class_='clickable departments')
|
grid = g.render(class_='hoverable departments')
|
||||||
return grids.render_grid(request, grid, search)
|
return grids.render_grid(request, grid, search)
|
||||||
|
|
||||||
|
|
||||||
|
@view_config(route_name='department.delete')
|
||||||
|
def delete_department(context, request):
|
||||||
|
uuid = request.matchdict['uuid']
|
||||||
|
dept = Session.query(rattail.Department).get(uuid) if uuid else None
|
||||||
|
assert dept
|
||||||
|
with transaction.manager:
|
||||||
|
q = Session.query(rattail.Product)
|
||||||
|
q = q.filter(rattail.Product.department_uuid == dept.uuid)
|
||||||
|
if q.count():
|
||||||
|
q.update({'department_uuid': None}, synchronize_session=False)
|
||||||
|
Session.delete(dept)
|
||||||
|
return HTTPFound(location=request.route_url('departments.list'))
|
||||||
|
|
||||||
|
|
||||||
def includeme(config):
|
def includeme(config):
|
||||||
config.add_route('department.list', '/departments')
|
config.add_route('departments.list', '/departments')
|
||||||
|
config.add_route('department.delete', '/department/{uuid}/delete')
|
||||||
config.scan(__name__)
|
config.scan(__name__)
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
|
|
||||||
from sqlalchemy.orm import joinedload
|
from sqlalchemy.orm import joinedload
|
||||||
|
|
||||||
|
import transaction
|
||||||
|
from pyramid.httpexceptions import HTTPFound
|
||||||
from pyramid.view import view_config
|
from pyramid.view import view_config
|
||||||
|
|
||||||
from edbob.pyramid import filters
|
from edbob.pyramid import filters
|
||||||
|
@ -36,59 +38,79 @@ from edbob.pyramid import grids
|
||||||
from edbob.pyramid import Session
|
from edbob.pyramid import Session
|
||||||
|
|
||||||
import rattail
|
import rattail
|
||||||
|
from rattail.batches import next_batch_id
|
||||||
|
from rattail.pyramid import util
|
||||||
from rattail.pyramid.forms import UpcFieldRenderer
|
from rattail.pyramid.forms import UpcFieldRenderer
|
||||||
|
|
||||||
|
|
||||||
@view_config(route_name='products', renderer='/products/index.mako')
|
def filter_map():
|
||||||
def products(context, request):
|
return filters.get_filter_map(
|
||||||
|
|
||||||
fmap = filters.get_filter_map(
|
|
||||||
rattail.Product,
|
rattail.Product,
|
||||||
exact=['upc'],
|
exact=['upc'],
|
||||||
ilike=['description'],
|
ilike=['description', 'size'],
|
||||||
|
department=filters.filter_ilike(rattail.Department.name),
|
||||||
brand=filters.filter_ilike(rattail.Brand.name))
|
brand=filters.filter_ilike(rattail.Brand.name))
|
||||||
|
|
||||||
config = filters.get_search_config(
|
def search_config(request, fmap):
|
||||||
'products', request, fmap,
|
return filters.get_search_config(
|
||||||
|
'products.list', request, fmap,
|
||||||
include_filter_brand=True,
|
include_filter_brand=True,
|
||||||
filter_type_brand='lk',
|
filter_type_brand='lk',
|
||||||
include_filter_description=True,
|
include_filter_description=True,
|
||||||
filter_type_description='lk')
|
filter_type_description='lk',
|
||||||
|
include_filter_department=True,
|
||||||
|
filter_type_department='lk')
|
||||||
|
|
||||||
search = filters.get_search_form(
|
def search_form(config):
|
||||||
|
return filters.get_search_form(
|
||||||
config, upc="UPC")
|
config, upc="UPC")
|
||||||
|
|
||||||
config = grids.get_grid_config(
|
def grid_config(request, search, fmap):
|
||||||
'products', request, search,
|
return grids.get_grid_config(
|
||||||
|
'products.list', request, search,
|
||||||
filter_map=fmap, sort='description')
|
filter_map=fmap, sort='description')
|
||||||
|
|
||||||
smap = grids.get_sort_map(
|
def sort_map():
|
||||||
|
return grids.get_sort_map(
|
||||||
rattail.Product,
|
rattail.Product,
|
||||||
['upc', 'description'],
|
['upc', 'description', 'size'],
|
||||||
|
department=grids.sorter(rattail.Department.name),
|
||||||
brand=grids.sorter(rattail.Brand.name))
|
brand=grids.sorter(rattail.Brand.name))
|
||||||
|
|
||||||
|
def query(config):
|
||||||
jmap = {
|
jmap = {
|
||||||
'brand':
|
'department': lambda q: q.outerjoin(rattail.Department),
|
||||||
lambda q: q.join(rattail.Brand),
|
'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
|
||||||
|
|
||||||
def query(config):
|
|
||||||
q = Session.query(rattail.Product)
|
|
||||||
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)
|
products = grids.get_pager(query, config)
|
||||||
|
|
||||||
g = forms.AlchemyGrid(
|
g = forms.AlchemyGrid(
|
||||||
rattail.Product, products, config,
|
rattail.Product, products, config,
|
||||||
request.route_url('products'))
|
gridurl=request.route_url('products.list'))
|
||||||
|
|
||||||
g.configure(
|
g.configure(
|
||||||
include=[
|
include=[
|
||||||
g.upc.with_renderer(UpcFieldRenderer).label("UPC"),
|
g.upc.with_renderer(UpcFieldRenderer).label("UPC"),
|
||||||
g.brand,
|
g.brand,
|
||||||
g.description,
|
g.description,
|
||||||
|
g.size,
|
||||||
|
g.department,
|
||||||
],
|
],
|
||||||
readonly=True)
|
readonly=True)
|
||||||
|
|
||||||
|
@ -96,6 +118,56 @@ def products(context, request):
|
||||||
return grids.render_grid(request, grid, search)
|
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):
|
def includeme(config):
|
||||||
config.add_route('products', '/products')
|
config.add_route('products.list', '/products')
|
||||||
|
config.add_route('products.batch', '/products/batch')
|
||||||
config.scan(__name__)
|
config.scan(__name__)
|
||||||
|
|
Loading…
Reference in a new issue