fix: add batch handler logic to remove row
also execute() can return whatever it wants, e.g. when creating some new record(s) based on batch data
This commit is contained in:
parent
6d16aa0c02
commit
b3ec7cb9b8
|
@ -296,6 +296,54 @@ class BatchHandler(GenericHandler):
|
||||||
that depending on the workflow.
|
that depending on the workflow.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def do_remove_row(self, row):
|
||||||
|
"""
|
||||||
|
Remove a row from its batch. This will:
|
||||||
|
|
||||||
|
* call :meth:`remove_row()`
|
||||||
|
* decrement the batch
|
||||||
|
:attr:`~wuttjamaican.db.model.batch.BatchMixin.row_count`
|
||||||
|
* call :meth:`refresh_batch_status()`
|
||||||
|
|
||||||
|
So, callers should use ``do_remove_row()``, but subclass
|
||||||
|
should (usually) override :meth:`remove_row()` etc.
|
||||||
|
"""
|
||||||
|
batch = row.batch
|
||||||
|
|
||||||
|
self.remove_row(row)
|
||||||
|
|
||||||
|
if batch.row_count is not None:
|
||||||
|
batch.row_count -= 1
|
||||||
|
|
||||||
|
self.refresh_batch_status(batch)
|
||||||
|
|
||||||
|
def remove_row(self, row):
|
||||||
|
"""
|
||||||
|
Remove a row from its batch.
|
||||||
|
|
||||||
|
Callers should use :meth:`do_remove_row()` instead, which
|
||||||
|
calls this method automatically.
|
||||||
|
|
||||||
|
Subclass can override this method; the default logic just
|
||||||
|
deletes the row.
|
||||||
|
"""
|
||||||
|
session = self.app.get_session(row)
|
||||||
|
session.delete(row)
|
||||||
|
|
||||||
|
def refresh_batch_status(self, batch):
|
||||||
|
"""
|
||||||
|
Update the batch status as needed.
|
||||||
|
|
||||||
|
This method is called when some row data has changed for the
|
||||||
|
batch, e.g. from :meth:`do_remove_row()`.
|
||||||
|
|
||||||
|
It does nothing by default; subclass may override to set these
|
||||||
|
attributes on the batch:
|
||||||
|
|
||||||
|
* :attr:`~wuttjamaican.db.model.batch.BatchMixin.status_code`
|
||||||
|
* :attr:`~wuttjamaican.db.model.batch.BatchMixin.status_text`
|
||||||
|
"""
|
||||||
|
|
||||||
def why_not_execute(self, batch, user=None, **kwargs):
|
def why_not_execute(self, batch, user=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Returns text indicating the reason (if any) that a given batch
|
Returns text indicating the reason (if any) that a given batch
|
||||||
|
@ -395,6 +443,9 @@ class BatchHandler(GenericHandler):
|
||||||
:param \**kwargs: Additional kwargs as needed. These are
|
:param \**kwargs: Additional kwargs as needed. These are
|
||||||
passed as-is to :meth:`why_not_execute()` and
|
passed as-is to :meth:`why_not_execute()` and
|
||||||
:meth:`execute()`.
|
:meth:`execute()`.
|
||||||
|
|
||||||
|
:returns: Whatever was returned from :meth:`execute()` - often
|
||||||
|
``None``.
|
||||||
"""
|
"""
|
||||||
if batch.executed:
|
if batch.executed:
|
||||||
raise ValueError(f"batch has already been executed: {batch}")
|
raise ValueError(f"batch has already been executed: {batch}")
|
||||||
|
@ -403,9 +454,10 @@ class BatchHandler(GenericHandler):
|
||||||
if reason:
|
if reason:
|
||||||
raise RuntimeError(f"batch execution not allowed: {reason}")
|
raise RuntimeError(f"batch execution not allowed: {reason}")
|
||||||
|
|
||||||
self.execute(batch, user=user, progress=progress, **kwargs)
|
result = self.execute(batch, user=user, progress=progress, **kwargs)
|
||||||
batch.executed = datetime.datetime.now()
|
batch.executed = datetime.datetime.now()
|
||||||
batch.executed_by = user
|
batch.executed_by = user
|
||||||
|
return result
|
||||||
|
|
||||||
def execute(self, batch, user=None, progress=None, **kwargs):
|
def execute(self, batch, user=None, progress=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
@ -428,6 +480,10 @@ class BatchHandler(GenericHandler):
|
||||||
:param \**kwargs: Additional kwargs which may affect the batch
|
:param \**kwargs: Additional kwargs which may affect the batch
|
||||||
execution behavior. There are none by default, but some
|
execution behavior. There are none by default, but some
|
||||||
handlers may declare/use them.
|
handlers may declare/use them.
|
||||||
|
|
||||||
|
:returns: ``None`` by default, but subclass can return
|
||||||
|
whatever it likes, in which case that will be also returned
|
||||||
|
to the caller from :meth:`do_execute()`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def do_delete(self, batch, user, dry_run=False, progress=None, **kwargs):
|
def do_delete(self, batch, user, dry_run=False, progress=None, **kwargs):
|
||||||
|
|
|
@ -115,6 +115,21 @@ else:
|
||||||
handler.add_row(batch, row)
|
handler.add_row(batch, row)
|
||||||
self.assertEqual(batch.row_count, 1)
|
self.assertEqual(batch.row_count, 1)
|
||||||
|
|
||||||
|
def test_remove_row(self):
|
||||||
|
model = self.app.model
|
||||||
|
handler = self.make_handler()
|
||||||
|
user = model.User(username='barney')
|
||||||
|
self.session.add(user)
|
||||||
|
batch = handler.make_batch(self.session, created_by=user)
|
||||||
|
self.session.add(batch)
|
||||||
|
row = handler.make_row()
|
||||||
|
handler.add_row(batch, row)
|
||||||
|
self.session.flush()
|
||||||
|
self.assertEqual(batch.row_count, 1)
|
||||||
|
handler.do_remove_row(row)
|
||||||
|
self.session.flush()
|
||||||
|
self.assertEqual(batch.row_count, 0)
|
||||||
|
|
||||||
def test_do_execute(self):
|
def test_do_execute(self):
|
||||||
model = self.app.model
|
model = self.app.model
|
||||||
user = model.User(username='barney')
|
user = model.User(username='barney')
|
||||||
|
|
Loading…
Reference in a new issue