Remove all views etc. for old-style batches

This commit is contained in:
Lance Edgar 2017-05-13 16:44:05 -05:00
parent 9e5b43ca66
commit 2d29174772
16 changed files with 45 additions and 906 deletions

View file

@ -55,14 +55,6 @@
<li>${h.link_to("Vendors", url('vendors'))}</li>
</ul>
</li>
% if request.has_perm('batches.list'):
<li>
<a>Batches</a>
<ul>
<li>${h.link_to("Batches", url('batches'))}</li>
</ul>
</li>
% endif
<li>
<a>Stores</a>
<ul>

View file

@ -1,12 +0,0 @@
## -*- coding: utf-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>
% if not form.readonly:
<li>${h.link_to("View this Batch", url('batch.read', uuid=form.fieldset.model.uuid))}</li>
% endif
</%def>
${parent.body()}

View file

@ -1,6 +0,0 @@
## -*- coding: utf-8 -*-
<%inherit file="/grid.mako" />
<%def name="title()">Batches</%def>
${parent.body()}

View file

@ -1,44 +0,0 @@
## -*- coding: utf-8 -*-
<%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.csrf_token(request)}
${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>

View file

@ -1,20 +0,0 @@
## -*- coding: utf-8 -*-
<%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()}

View file

@ -1,41 +0,0 @@
## -*- coding: utf-8 -*-
<%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>

View file

@ -1,9 +0,0 @@
## -*- coding: utf-8 -*-
<%inherit file="/crud.mako" />
<%def name="context_menu_items()">
<li>${h.link_to("Back to Batch", url('batch.read', 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()}

View file

@ -1,47 +0,0 @@
## -*- coding: utf-8 -*-
<%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.read', 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()}

View file

@ -9,38 +9,34 @@
<%def name="extra_javascript()">
${parent.extra_javascript()}
% if legacy_mode is Undefined:
<script type="text/javascript">
$(function() {
$('#batch_type').selectmenu({
change: function(event, ui) {
$('.params-wrapper').hide();
$('.params-wrapper.' + ui.item.value).show();
}
});
$('.params-wrapper.' + $('#batch_type').val()).show();
$('#make-batch').click(function() {
$(this).button('disable').button('option', 'label', "Working, please wait...");
$(this).parents('form:first').submit();
});
<script type="text/javascript">
$(function() {
$('#batch_type').selectmenu({
change: function(event, ui) {
$('.params-wrapper').hide();
$('.params-wrapper.' + ui.item.value).show();
}
});
</script>
% endif
$('.params-wrapper.' + $('#batch_type').val()).show();
$('#make-batch').click(function() {
$(this).button('disable').button('option', 'label', "Working, please wait...");
$(this).parents('form:first').submit();
});
});
</script>
</%def>
<%def name="extra_styles()">
${parent.extra_styles()}
% if legacy_mode is Undefined:
<style type="text/css">
.params-wrapper {
display: none;
}
</style>
% endif
<style type="text/css">
.params-wrapper {
display: none;
}
</style>
</%def>
<ul id="context-menu">
@ -51,38 +47,20 @@
${h.form(request.current_route_url())}
${h.csrf_token(request)}
% if legacy_mode is not Undefined:
${self.wtfield(form, 'batch_type')}
<div class="field-wrapper">
<label for="provider">Batch Type</label>
<div class="field">
${h.select('provider', None, providers)}
</div>
% for key, pform in params_forms.items():
<div class="params-wrapper ${key}">
% for name in pform._fields:
${self.wtfield(pform, name)}
% endfor
</div>
% endfor
<div class="buttons">
${h.submit('create', "Create Batch")}
${h.link_to("Cancel", url('products'), class_='button')}
</div>
% else: ## new-style batches
${self.wtfield(form, 'batch_type')}
% for key, pform in params_forms.items():
<div class="params-wrapper ${key}">
% for name in pform._fields:
${self.wtfield(pform, name)}
% endfor
</div>
% endfor
<div class="buttons">
<button type="button" id="make-batch">Create Batch</button>
${h.link_to("Cancel", url('products'), class_='button')}
</div>
% endif
<div class="buttons">
<button type="button" id="make-batch">Create Batch</button>
${h.link_to("Cancel", url('products'), class_='button')}
</div>
${h.end_form()}
</div>

View file

@ -75,5 +75,4 @@ def includeme(config):
config.include('tailbone.views.vendors')
# batch views
config.include('tailbone.views.batches')
config.include('tailbone.views.batch.pricing')

View file

@ -1,35 +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/>.
#
################################################################################
"""
Batch Views
"""
from .params import *
def includeme(config):
config.include('tailbone.views.batches.core')
config.include('tailbone.views.batches.params')
config.include('tailbone.views.batches.rows')

View file

@ -1,202 +0,0 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2016 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/>.
#
################################################################################
"""
Core Batch Views
"""
from __future__ import unicode_literals, absolute_import
from pyramid.httpexceptions import HTTPFound
from pyramid.renderers import render_to_response
from webhelpers.html import tags
from tailbone import forms
from ...grids.search import BooleanSearchFilter
from .. import SearchableAlchemyGridView, CrudView, View
from ...progress import SessionProgress
from rattail import enum
from rattail import batches
from rattail.db.util import configure_session
from ...db import Session
from rattail.db.model import Batch
from rattail.threads import Thread
class BatchesGrid(SearchableAlchemyGridView):
mapped_class = Batch
config_prefix = 'batches'
sort = 'id'
def filter_map(self):
def executed_is(q, v):
if v == 'True':
return q.filter(Batch.executed != None)
else:
return q.filter(Batch.executed == None)
def executed_isnot(q, v):
if v == 'True':
return q.filter(Batch.executed == None)
else:
return q.filter(Batch.executed != None)
return self.make_filter_map(
exact=['id'],
ilike=['source', 'destination', 'description'],
executed={
'is': executed_is,
'nt': executed_isnot,
})
def filter_config(self):
return self.make_filter_config(
filter_label_id="ID",
filter_factory_executed=BooleanSearchFilter,
include_filter_executed=True,
filter_type_executed='is',
executed='False')
def sort_map(self):
return self.make_sort_map('source', 'id', 'destination', 'description', 'executed')
def grid(self):
g = self.make_grid()
g.configure(
include=[
g.source,
g.id.label("ID"),
g.destination,
g.description,
g.executed,
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.viewable = True
g.view_route_name = 'batch.read'
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 = Batch
home_route = 'batches'
def fieldset(self, model):
fs = self.make_fieldset(model)
fs.action_type.set(renderer=forms.renderers.EnumFieldRenderer(enum.BATCH_ACTION))
fs.configure(
include=[
fs.source,
fs.id.label("ID"),
fs.destination,
fs.action_type,
fs.description,
fs.rowcount.label("Row Count").readonly(),
fs.executed.readonly(),
])
return fs
def post_delete(self, batch):
batch.drop_table()
class ExecuteBatch(View):
def execute_batch(self, batch, progress):
from rattail.db import Session
session = Session()
configure_session(self.request.rattail_config, session)
batch = session.merge(batch)
if not batch.execute(self.request.rattail_config, progress):
session.rollback()
session.close()
return
session.commit()
session.refresh(batch)
session.close()
progress.session.load()
progress.session['complete'] = True
progress.session['success_msg'] = "Batch \"%s\" has been executed." % batch.description
progress.session['success_url'] = self.request.route_url('batches')
progress.session.save()
def __call__(self):
uuid = self.request.matchdict['uuid']
batch = Session.query(Batch).get(uuid) if uuid else None
if not batch:
return HTTPFound(location=self.request.route_url('batches'))
progress = SessionProgress(self.request, 'batch.execute')
thread = Thread(target=self.execute_batch, args=(batch, progress))
thread.start()
kwargs = {
'key': 'batch.execute',
'cancel_url': self.request.route_url('batch.rows', uuid=batch.uuid),
'cancel_msg': "Batch execution was canceled.",
}
return self.render_progress(kwargs)
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.read', '/batches/{uuid}')
config.add_view(BatchCrud, attr='read',
route_name='batch.read',
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')

View file

@ -1,52 +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/>.
#
################################################################################
"""
Batch Parameter Views
"""
from ... 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('tailbone.views.batches.params.labels')

View file

@ -1,52 +0,0 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2014 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/>.
#
################################################################################
"""
Print Labels Batch
"""
from __future__ import unicode_literals
from rattail.db import model
from tailbone.db import Session
from tailbone.views.batches.params import BatchParamsView
class PrintLabels(BatchParamsView):
provider_name = 'print_labels'
def render_kwargs(self):
q = Session.query(model.LabelProfile)
q = q.order_by(model.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')

View file

@ -1,252 +0,0 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2016 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/>.
#
################################################################################
"""
Batch Row Views
"""
from __future__ import unicode_literals, absolute_import
from pyramid.httpexceptions import HTTPFound
from tailbone.views import SearchableAlchemyGridView, CrudView
from tailbone.forms import GPCFieldRenderer
from tailbone.grids.search import BooleanSearchFilter
from tailbone.db import Session
from rattail.db import model
from rattail.db.model import Batch, LabelProfile
from rattail.gpc import GPC
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(LabelProfile)
q = q.order_by(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(Batch).get(uuid) if uuid else None
if not batch:
raise 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):
# TODO: This code is copied from `tailbone.views.products`, which
# means we probably should refactor...
def filter_F01_is(q, v):
if not v:
return q
try:
return q.filter(model.Product.upc.in_((
GPC(v), GPC(v, calc_check_digit='upc'))))
except ValueError:
return q
def filter_F01_not(q, v):
if not v:
return q
try:
return q.filter(~model.Product.upc.in_((
GPC(v), GPC(v, calc_check_digit='upc'))))
except ValueError:
return q
fmap = self.make_filter_map()
for column in batch.columns:
if column.sil_name == 'F01':
fmap[column.name] = {'is': filter_F01_is,
'nt': filter_F01_not}
elif 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
if column.data_type == 'FLAG(1)':
config['filter_factory_{0}'.format(column.name)] = BooleanSearchFilter
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.viewable = True
g.view_route_name = 'batch_row.read'
g.view_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):
result = BatchRowsGrid(request)
if isinstance(result, HTTPFound):
return result
return result()
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)
grid.batch.rowcount -= count
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(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.read', 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')

View file

@ -26,14 +26,13 @@ Product Views
from __future__ import unicode_literals, absolute_import
import os
import re
import six
import sqlalchemy as sa
from sqlalchemy import orm
from rattail import enum, pod, sil, batches
from rattail import enum, pod, sil
from rattail.db import model, api, auth, Session as RattailSession
from rattail.gpc import GPC
from rattail.threads import Thread
@ -425,14 +424,6 @@ class ProductsView(MasterView):
"""
View for making a new batch from current product grid query.
"""
# maybe do legacy mode
enabled = self.rattail_config.getlist('rattail.pyramid', 'batches.providers')
if enabled:
supported = batches.get_providers()
providers = dict([(key, supported[key]) for key in enabled if key in supported])
return self.make_batch_legacy(providers)
# okay then, new-style it is
supported = self.get_supported_batches()
batch_options = []
for key, spec in list(supported.items()):
@ -512,65 +503,13 @@ class ProductsView(MasterView):
if batch.batch_key == 'pricing':
return self.request.route_url('batch.pricing.view', uuid=batch.uuid)
def make_batch_legacy(self, providers):
if self.request.method == 'POST':
provider_key = self.request.POST.get('provider')
if provider_key:
provider_factory = providers.get(provider_key)
if provider_factory:
provider = provider_factory(self.rattail_config)
if self.request.POST.get('params') == 'True':
provider.set_params(Session(), **self.request.POST)
else:
try:
url = self.request.route_url('batch_params.{}'.format(provider.name))
except KeyError:
pass
else:
self.request.session['referer'] = self.request.current_route_url()
return httpexceptions.HTTPFound(location=url)
progress = SessionProgress(self.request, 'products.batch')
thread = Thread(target=self.make_batch_thread_legacy, args=(provider, progress))
thread.start()
kwargs = {
'key': 'products.batch',
'cancel_url': self.request.route_url('products'),
'cancel_msg': "Batch creation was canceled.",
}
return self.render_progress(kwargs)
providers = [(p.name, p.description)
for p in sorted(providers.itervalues(),
key=lambda p: p.description)]
return {'legacy_mode': True, 'providers': providers}
def make_batch_thread_legacy(self, provider, progress):
"""
Threat target for making a batch from current products query.
"""
session = RattailSession()
products = self.get_effective_query(session)
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['complete'] = True
progress.session['success_url'] = self.request.route_url('batch.read', uuid=batch.uuid)
progress.session['success_msg'] = 'Batch "{}" has been created.'.format(batch.description)
progress.session.save()
@classmethod
def defaults(cls, config):
route_prefix = cls.get_route_prefix()
url_prefix = cls.get_url_prefix()
template_prefix = cls.get_template_prefix()
permission_prefix = cls.get_permission_prefix()
model_title = cls.get_model_title()
# print labels
config.add_tailbone_permission('products', 'products.print_labels',
@ -581,9 +520,12 @@ class ProductsView(MasterView):
"View products marked as deleted")
# make batch from product query
config.add_route('products.create_batch', '/products/make-batch')
config.add_view(cls, attr='make_batch', route_name='products.create_batch',
renderer='/products/batch.mako', permission='batches.create')
config.add_tailbone_permission(permission_prefix, '{}.make_batch'.format(permission_prefix),
"Create batch from {} query".format(model_title))
config.add_route('{}.make_batch'.format(route_prefix), '{}/make-batch'.format(url_prefix))
config.add_view(cls, attr='make_batch', route_name='{}.make_batch'.format(route_prefix),
renderer='{}/batch.mako'.format(template_prefix),
permission='{}.make_batch'.format(permission_prefix))
# search (by upc)
config.add_route('products.search', '/products/search')