Optimize "auto-receive" batch process

disable versioning when doing "auto-receive" for a receiving batch
This commit is contained in:
Lance Edgar 2023-07-06 21:23:44 -05:00
parent 8742a03e18
commit 58f9b3ce2a
2 changed files with 29 additions and 64 deletions

View file

@ -931,7 +931,7 @@ class BatchMasterView(MasterView):
prefix = self.rattail_config.get('rattail', 'command_prefix', prefix = self.rattail_config.get('rattail', 'command_prefix',
default=sys.prefix) default=sys.prefix)
cmd = [os.path.join(prefix, 'bin/{}'.format(command))] cmd = [os.path.join(prefix, 'bin/{}'.format(command))]
for path in self.rattail_config.files_read: for path in reversed(self.rattail_config.files_read):
cmd.extend(['--config', path]) cmd.extend(['--config', path])
if username: if username:
cmd.extend(['--runas', username]) cmd.extend(['--runas', username])
@ -969,6 +969,10 @@ class BatchMasterView(MasterView):
batch_uuid = key[0] batch_uuid = key[0]
# figure out the (sub)command args we'll be passing # figure out the (sub)command args we'll be passing
if handler_action == 'auto_receive':
subcommand = 'auto-receive'
else:
subcommand = f'{handler_action}-batch'
subargs = [ subargs = [
'--batch-type', '--batch-type',
self.handler.batch_key, self.handler.batch_key,
@ -987,7 +991,7 @@ class BatchMasterView(MasterView):
command_args=[ command_args=[
'--no-versioning', '--no-versioning',
], ],
subcommand='{}-batch'.format(handler_action), subcommand=subcommand,
subcommand_args=subargs) subcommand_args=subargs)
except Exception as error: except Exception as error:
log.warning("%s of '%s' batch failed: %s", handler_action, self.handler.batch_key, batch_uuid, exc_info=True) log.warning("%s of '%s' batch failed: %s", handler_action, self.handler.batch_key, batch_uuid, exc_info=True)

View file

@ -34,10 +34,8 @@ import humanize
import sqlalchemy as sa import sqlalchemy as sa
from rattail import pod from rattail import pod
from rattail.db import model, Session as RattailSession
from rattail.time import localtime, make_utc from rattail.time import localtime, make_utc
from rattail.util import pretty_quantity, prettify, simple_error from rattail.util import pretty_quantity, prettify, simple_error
from rattail.threads import Thread
import colander import colander
from deform import widget as dfwidget from deform import widget as dfwidget
@ -252,6 +250,7 @@ class ReceivingBatchView(PurchasingBatchView):
:meth:`tailbone.views.purchasing.costing:CostingBatchView.create()` :meth:`tailbone.views.purchasing.costing:CostingBatchView.create()`
which uses similar logic. which uses similar logic.
""" """
model = self.model
route_prefix = self.get_route_prefix() route_prefix = self.get_route_prefix()
workflows = self.handler.supported_receiving_workflows() workflows = self.handler.supported_receiving_workflows()
valid_workflows = [workflow['workflow_key'] valid_workflows = [workflow['workflow_key']
@ -642,7 +641,8 @@ class ReceivingBatchView(PurchasingBatchView):
return params return params
def template_kwargs_create(self, **kwargs): def template_kwargs_create(self, **kwargs):
kwargs = super(ReceivingBatchView, self).template_kwargs_create(**kwargs) kwargs = super().template_kwargs_create(**kwargs)
model = self.model
if self.handler.allow_truck_dump_receiving(): if self.handler.allow_truck_dump_receiving():
vmap = {} vmap = {}
batches = self.Session.query(model.PurchaseBatch)\ batches = self.Session.query(model.PurchaseBatch)\
@ -931,16 +931,17 @@ class ReceivingBatchView(PurchasingBatchView):
url = self.request.route_url('receiving.view', uuid=truck_dump.uuid) url = self.request.route_url('receiving.view', uuid=truck_dump.uuid)
return tags.link_to(text, url) return tags.link_to(text, url)
@staticmethod # TODO: is this actually used? wait to see if something breaks..
@colander.deferred # @staticmethod
def validate_purchase(node, kw): # @colander.deferred
session = kw['session'] # def validate_purchase(node, kw):
def validate(node, value): # session = kw['session']
purchase = session.get(model.Purchase, value) # def validate(node, value):
if not purchase: # purchase = session.get(model.Purchase, value)
raise colander.Invalid(node, "Purchase not found") # if not purchase:
return purchase.uuid # raise colander.Invalid(node, "Purchase not found")
return validate # return purchase.uuid
# return validate
def assign_purchase_order(self, batch, po_form): def assign_purchase_order(self, batch, po_form):
""" """
@ -957,7 +958,8 @@ class ReceivingBatchView(PurchasingBatchView):
batch.department_uuid = department.uuid batch.department_uuid = department.uuid
def configure_row_grid(self, g): def configure_row_grid(self, g):
super(ReceivingBatchView, self).configure_row_grid(g) super().configure_row_grid(g)
model = self.model
batch = self.get_instance() batch = self.get_instance()
# vendor_code # vendor_code
@ -1469,6 +1471,7 @@ class ReceivingBatchView(PurchasingBatchView):
a "pack" item, such that it instead associates with the "unit" item, a "pack" item, such that it instead associates with the "unit" item,
with quantities adjusted accordingly. with quantities adjusted accordingly.
""" """
model = self.model
batch = self.get_instance() batch = self.get_instance()
row_uuid = self.request.params.get('row_uuid') row_uuid = self.request.params.get('row_uuid')
@ -1513,7 +1516,8 @@ class ReceivingBatchView(PurchasingBatchView):
}) })
def configure_row_form(self, f): def configure_row_form(self, f):
super(ReceivingBatchView, self).configure_row_form(f) super().configure_row_form(f)
model = self.model
batch = self.get_instance() batch = self.get_instance()
# when viewing a row which has no product reference, enable # when viewing a row which has no product reference, enable
@ -1690,6 +1694,7 @@ class ReceivingBatchView(PurchasingBatchView):
return True return True
def save_edit_row_form(self, form): def save_edit_row_form(self, form):
model = self.model
batch = self.get_instance() batch = self.get_instance()
row = self.objectify(form) row = self.objectify(form)
@ -1829,6 +1834,7 @@ class ReceivingBatchView(PurchasingBatchView):
""" """
AJAX view for updating various cost fields in a data row. AJAX view for updating various cost fields in a data row.
""" """
model = self.model
batch = self.get_instance() batch = self.get_instance()
data = dict(get_form_data(self.request)) data = dict(get_form_data(self.request))
@ -1882,55 +1888,10 @@ class ReceivingBatchView(PurchasingBatchView):
def auto_receive(self): def auto_receive(self):
""" """
View which can "auto-receive" all items in the batch. Meant only as a View which can "auto-receive" all items in the batch.
convenience for developers.
""" """
batch = self.get_instance() batch = self.get_instance()
key = '{}.receive_all'.format(self.get_grid_key()) return self.handler_action(batch, 'auto_receive')
progress = self.make_progress(key)
kwargs = {'progress': progress}
thread = Thread(target=self.auto_receive_thread, args=(batch.uuid, self.request.user.uuid), kwargs=kwargs)
thread.start()
return self.render_progress(progress, {
'instance': batch,
'cancel_url': self.get_action_url('view', batch),
'cancel_msg': "Auto-receive was canceled",
})
def auto_receive_thread(self, uuid, user_uuid, progress=None):
"""
Thread target for receiving all items on the given batch.
"""
session = RattailSession()
batch = session.get(model.PurchaseBatch, uuid)
# user = session.query(model.User).get(user_uuid)
try:
self.handler.auto_receive_all_items(batch, progress=progress)
# if anything goes wrong, rollback and log the error etc.
except Exception as error:
session.rollback()
log.exception("auto-receive failed for: %s".format(batch))
session.close()
if progress:
progress.session.load()
progress.session['error'] = True
progress.session['error_msg'] = "Auto-receive failed: {}".format(
simple_error(error))
progress.session.save()
# if no error, check result flag (false means user canceled)
else:
session.commit()
session.refresh(batch)
success_url = self.get_action_url('view', batch)
session.close()
if progress:
progress.session.load()
progress.session['complete'] = True
progress.session['success_url'] = success_url
progress.session.save()
def configure_get_simple_settings(self): def configure_get_simple_settings(self):
config = self.rattail_config config = self.rattail_config