Add initial support for vendor invoice batch feature, etc.
Also included: * Add "edit batch" template, refactor "view batch" template. * Tweak form templates to allow specifying form ID and buttons HTML. * Make deleting batch rows only work when editing a batch.
This commit is contained in:
parent
aee69f5a2c
commit
2e8db05717
15 changed files with 387 additions and 92 deletions
|
@ -37,7 +37,7 @@ import formalchemy
|
|||
from pyramid.renderers import render_to_response
|
||||
from pyramid.response import FileResponse
|
||||
from pyramid.httpexceptions import HTTPFound, HTTPNotFound
|
||||
from webhelpers.html.tags import link_to
|
||||
from webhelpers.html.tags import link_to, HTML
|
||||
|
||||
from rattail.db import model
|
||||
from rattail.db import Session as RatSession
|
||||
|
@ -234,9 +234,9 @@ class BatchGrid(BaseGrid):
|
|||
if self.request.has_perm('{0}.view'.format(self.permission_prefix)):
|
||||
g.viewable = True
|
||||
g.view_route_name = '{0}.view'.format(self.route_prefix)
|
||||
# if self.request.has_perm('{0}.edit'.format(self.permission_prefix)):
|
||||
# g.editable = True
|
||||
# g.edit_route_name = '{0}.edit'.format(self.route_prefix)
|
||||
if self.request.has_perm('{0}.edit'.format(self.permission_prefix)):
|
||||
g.editable = True
|
||||
g.edit_route_name = '{0}.edit'.format(self.route_prefix)
|
||||
if self.request.has_perm('{0}.delete'.format(self.permission_prefix)):
|
||||
g.deletable = True
|
||||
g.delete_route_name = '{0}.delete'.format(self.route_prefix)
|
||||
|
@ -321,6 +321,12 @@ class BaseCrud(CrudView):
|
|||
else:
|
||||
super(BaseCrud, self).flash_create(model)
|
||||
|
||||
def flash_update(self, model):
|
||||
if 'update' in self.flash:
|
||||
self.request.session.flash(self.flash['update'])
|
||||
else:
|
||||
super(BaseCrud, self).flash_update(model)
|
||||
|
||||
def flash_delete(self, model):
|
||||
if 'delete' in self.flash:
|
||||
self.request.session.flash(self.flash['delete'])
|
||||
|
@ -414,6 +420,33 @@ class BatchCrud(BaseCrud):
|
|||
fs.executed_by,
|
||||
])
|
||||
|
||||
def update(self):
|
||||
"""
|
||||
Don't allow editing a batch which has already been executed.
|
||||
"""
|
||||
batch = self.get_model_from_request()
|
||||
if not batch:
|
||||
return HTTPNotFound()
|
||||
if batch.executed:
|
||||
return HTTPFound(location=self.view_url(batch.uuid))
|
||||
return self.crud(batch)
|
||||
|
||||
def post_create_url(self, form):
|
||||
"""
|
||||
Redirect to view batch after creating a batch.
|
||||
"""
|
||||
batch = form.fieldset.model
|
||||
return self.view_url(batch.uuid)
|
||||
|
||||
def post_update_url(self, form):
|
||||
"""
|
||||
Redirect back to edit batch page after editing a batch, unless the
|
||||
refresh flag is set, in which case do that.
|
||||
"""
|
||||
if self.request.params.get('refresh') == 'true':
|
||||
return self.refresh_url()
|
||||
return self.request.current_route_url()
|
||||
|
||||
def template_kwargs(self, form):
|
||||
"""
|
||||
Add some things to the template context: current batch model, batch
|
||||
|
@ -425,6 +458,7 @@ class BatchCrud(BaseCrud):
|
|||
'batch': batch,
|
||||
'batch_display': self.batch_display,
|
||||
'batch_display_plural': self.batch_display_plural,
|
||||
'execute_title': self.handler.get_execute_title(batch),
|
||||
'route_prefix': self.route_prefix,
|
||||
'permission_prefix': self.permission_prefix,
|
||||
}
|
||||
|
@ -511,6 +545,14 @@ class BatchCrud(BaseCrud):
|
|||
uuid = self.request.matchdict['uuid']
|
||||
return self.request.route_url('{0}.view'.format(self.route_prefix), uuid=uuid)
|
||||
|
||||
def refresh_url(self, uuid=None):
|
||||
"""
|
||||
Returns the URL for refreshing a batch; defaults to current batch.
|
||||
"""
|
||||
if uuid is None:
|
||||
uuid = self.request.matchdict['uuid']
|
||||
return self.request.route_url('{0}.refresh'.format(self.route_prefix), uuid=uuid)
|
||||
|
||||
def execute(self):
|
||||
batch = self.current_batch()
|
||||
if self.handler.execute(batch):
|
||||
|
@ -561,15 +603,15 @@ class FileBatchCrud(BatchCrud):
|
|||
override this, but :meth:`configure_fieldset()` instead.
|
||||
"""
|
||||
fs = self.make_fieldset(model)
|
||||
fs.created.set(label="Uploaded", renderer=DateTimeFieldRenderer(self.request.rattail_config))
|
||||
fs.created_by.set(label="Uploaded by", renderer=UserFieldRenderer)
|
||||
fs.created.set(label="Uploaded", renderer=DateTimeFieldRenderer(self.request.rattail_config), readonly=True)
|
||||
fs.created_by.set(label="Uploaded by", renderer=UserFieldRenderer, readonly=True)
|
||||
fs.cognized.set(renderer=DateTimeFieldRenderer(self.request.rattail_config))
|
||||
fs.cognized_by.set(label="Cognized by", renderer=UserFieldRenderer)
|
||||
fs.executed.set(renderer=DateTimeFieldRenderer(self.request.rattail_config))
|
||||
fs.executed_by.set(label="Executed by", renderer=UserFieldRenderer)
|
||||
fs.append(formalchemy.Field('data_file'))
|
||||
fs.data_file.set(renderer=formalchemy.fields.FileFieldRenderer)
|
||||
fs.filename.set(renderer=DownloadLinkRenderer(self.route_prefix))
|
||||
fs.filename.set(renderer=DownloadLinkRenderer(self.route_prefix), readonly=True)
|
||||
self.configure_fieldset(fs)
|
||||
if self.creating:
|
||||
del fs.created
|
||||
|
@ -660,13 +702,6 @@ class FileBatchCrud(BatchCrud):
|
|||
return HTTPFound(location=self.request.route_url(
|
||||
'{0}.create'.format(self.route_prefix)))
|
||||
|
||||
def post_save_url(self, form):
|
||||
"""
|
||||
Redirect to "view batch" after creating or updating a batch.
|
||||
"""
|
||||
batch = form.fieldset.model
|
||||
return self.view_url(batch.uuid)
|
||||
|
||||
def pre_delete(self, batch):
|
||||
"""
|
||||
Delete all data (files etc.) for the batch.
|
||||
|
@ -690,6 +725,23 @@ class FileBatchCrud(BatchCrud):
|
|||
return response
|
||||
|
||||
|
||||
class StatusRenderer(EnumFieldRenderer):
|
||||
"""
|
||||
Custom renderer for ``status_code`` fields. Adds ``status_text`` value as
|
||||
title attribute if it exists.
|
||||
"""
|
||||
|
||||
def render_readonly(self, **kwargs):
|
||||
value = self.raw_value
|
||||
if value is None:
|
||||
return ''
|
||||
status_code_text = self.enumeration.get(value, unicode(value))
|
||||
row = self.field.parent.model
|
||||
if row.status_text:
|
||||
return HTML.tag('span', title=row.status_text, c=status_code_text)
|
||||
return status_code_text
|
||||
|
||||
|
||||
class BatchRowGrid(BaseGrid):
|
||||
"""
|
||||
Base grid view for batch rows, which can be filtered and sorted. Also it
|
||||
|
@ -778,14 +830,16 @@ class BatchRowGrid(BaseGrid):
|
|||
g = self.make_grid()
|
||||
g.extra_row_class = self.tr_class
|
||||
g.sequence.set(label="Seq.")
|
||||
g.status_code.set(label="Status", renderer=EnumFieldRenderer(self.row_class.STATUS))
|
||||
g.status_code.set(label="Status", renderer=StatusRenderer(self.row_class.STATUS))
|
||||
self._configure_grid(g)
|
||||
self.configure_grid(g)
|
||||
|
||||
batch = self.current_batch()
|
||||
# g.viewable = True
|
||||
# g.view_route_name = '{0}.rows.view'.format(self.route_prefix)
|
||||
if not batch.executed and self.request.has_perm('{0}.edit'.format(self.permission_prefix)):
|
||||
# TODO: Fix this check for edit mode.
|
||||
edit_mode = self.request.referrer.endswith('/edit')
|
||||
if edit_mode and not batch.executed and self.request.has_perm('{0}.edit'.format(self.permission_prefix)):
|
||||
# g.editable = True
|
||||
# g.edit_route_name = '{0}.rows.edit'.format(self.route_prefix)
|
||||
g.deletable = True
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue