Add basic "auto-execute" logic for new batches created via filemon

this is for the sake of label batches in particular, when deploying several
copies from host to all store nodes
This commit is contained in:
Lance Edgar 2017-11-29 18:22:50 -06:00
parent 76b8856854
commit 827d8cf924
3 changed files with 44 additions and 8 deletions

View file

@ -31,6 +31,7 @@ import logging
from rattail.db import Session, model
from rattail.config import parse_bool
from rattail.filemon import Action
from rattail.time import make_utc
from rattail.util import load_object
@ -43,7 +44,9 @@ class MakeBatch(Action):
handles the simple case of creating a batch with a single input data file.
"""
def __call__(self, path, batch_type='', handler='', user='', delete_if_empty='false', **kwargs):
def __call__(self, path, batch_type='', handler='', user='',
delete_if_empty='false', auto_execute_allowed='true',
**kwargs):
"""
Make a batch from the given file path.
@ -61,13 +64,20 @@ class MakeBatch(Action):
:param delete_if_empty: Set this to 'true' if you wish the batch to be
auto-deleted in the event that it has no data rows, after being
initially populated from the given data file.
:param auto_execute_allowed: Set this to 'false' if you wish to disable
auto-execution of new batches. Default behavior is for the handler
to decide whether each batch is eligible for auto-execution. Note
that it is not possible to "force" auto-execution of a batch; you
may only "allow" or "prevent" it.
"""
if not handler:
assert batch_type
handler = self.config.require('rattail.batch', '{}.handler'.format(batch_type))
handler = load_object(handler)(self.config)
session = Session()
kwargs['created_by'] = session.query(model.User).filter_by(username=user).one()
user = session.query(model.User).filter_by(username=user).one()
kwargs['created_by'] = user
batch = handler.make_batch(session, **kwargs)
handler.set_input_file(batch, path)
handler.populate(batch)
@ -79,6 +89,12 @@ class MakeBatch(Action):
log.debug("auto-deleting empty '{}' batch: {}".format(handler.batch_key, batch))
batch.delete_data(self.config)
session.delete(batch)
batch = None
if batch and parse_bool(auto_execute_allowed) and handler.auto_executable(batch):
handler.execute(batch, user=user)
batch.executed = make_utc()
batch.executed_by = user
session.commit()
session.close()

View file

@ -308,6 +308,13 @@ class BatchHandler(object):
return True
return not bool(batch.executed)
def auto_executable(self, batch):
"""
Must return a boolean indicating whether the given bath is eligible for
"automatic" execution, i.e. immediately after batch is created.
"""
return False
def execute(self, batch, progress=None, **kwargs):
"""
Execute the given batch, with given progress and kwargs. That is an

View file

@ -37,6 +37,7 @@ from rattail import enum
from rattail.db import model, api
from rattail.gpc import GPC
from rattail.batch import BatchHandler
from rattail.csvutil import UnicodeDictReader
from rattail.util import progress_loop
from rattail.time import make_utc
from rattail.config import parse_bool
@ -67,6 +68,15 @@ class LabelBatchHandler(BatchHandler):
self.calc_check_digit = parse_bool(self.calc_check_digit)
return super(LabelBatchHandler, self).make_batch(session, progress, **kwargs)
def auto_executable(self, batch):
"""
Must return a boolean indicating whether the given bath is eligible for
"automatic" execution, i.e. immediately after batch is created.
"""
if batch.filename and '.autoexecute.' in batch.filename:
return True
return False
def populate(self, batch, progress=None):
"""
Pre-fill batch with row data from handheld batch, etc.
@ -118,13 +128,16 @@ class LabelBatchHandler(BatchHandler):
if self.skip_first_line:
f.readline()
reader = csv.reader(f)
data = [{'upc': row[0]} for row in reader]
else:
reader = UnicodeDictReader(f)
data = list(reader)
products = []
session = orm.object_session(batch)
def append(entry, i):
upc = entry[0].strip()
upc = entry['upc'].strip()
if upc:
upc = GPC(upc, calc_check_digit=self.calc_check_digit)
product = api.get_product_by_upc(session, upc)
@ -133,8 +146,8 @@ class LabelBatchHandler(BatchHandler):
else:
log.warning("product not found: {}".format(upc))
if self.progress_loop(append, data, progress,
message="Reading data from CSV file"):
self.progress_loop(append, data, progress,
message="Reading data from CSV file")
return products
def get_label_profile(self, session):