3
0
Fork 0

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:
Lance Edgar 2025-01-02 19:48:26 -06:00
parent 6d16aa0c02
commit b3ec7cb9b8
2 changed files with 72 additions and 1 deletions

View file

@ -296,6 +296,54 @@ class BatchHandler(GenericHandler):
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):
"""
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
passed as-is to :meth:`why_not_execute()` and
:meth:`execute()`.
:returns: Whatever was returned from :meth:`execute()` - often
``None``.
"""
if batch.executed:
raise ValueError(f"batch has already been executed: {batch}")
@ -403,9 +454,10 @@ class BatchHandler(GenericHandler):
if 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_by = user
return result
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
execution behavior. There are none by default, but some
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):

View file

@ -115,6 +115,21 @@ else:
handler.add_row(batch, row)
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):
model = self.app.model
user = model.User(username='barney')