Add new 'receiving form' for purchase batches
This commit is contained in:
parent
468a84aa90
commit
6c3d221e98
5 changed files with 323 additions and 36 deletions
|
@ -26,9 +26,12 @@ Views for purchase order batches
|
|||
|
||||
from __future__ import unicode_literals, absolute_import
|
||||
|
||||
import re
|
||||
import logging
|
||||
|
||||
from sqlalchemy import orm
|
||||
|
||||
from rattail import enum
|
||||
from rattail import enum, pod
|
||||
from rattail.db import model, api
|
||||
from rattail.gpc import GPC
|
||||
from rattail.time import localtime
|
||||
|
@ -36,6 +39,7 @@ from rattail.core import Object
|
|||
from rattail.util import OrderedDict
|
||||
|
||||
import formalchemy as fa
|
||||
import formencode as fe
|
||||
from pyramid import httpexceptions
|
||||
|
||||
from tailbone import forms
|
||||
|
@ -43,6 +47,21 @@ from tailbone.db import Session
|
|||
from tailbone.views.batch import BatchMasterView
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ReceivingForm(forms.Schema):
|
||||
allow_extra_fields = True
|
||||
filter_extra_fields = True
|
||||
mode = fe.validators.OneOf([
|
||||
'received',
|
||||
# 'damaged', 'expired', 'mispick',
|
||||
])
|
||||
product = forms.validators.ValidProduct()
|
||||
cases = fe.validators.Int()
|
||||
units = fe.validators.Int()
|
||||
|
||||
|
||||
class PurchaseBatchView(BatchMasterView):
|
||||
"""
|
||||
Master view for purchase order batches.
|
||||
|
@ -578,6 +597,95 @@ class PurchaseBatchView(BatchMasterView):
|
|||
'batch_po_total': '${:0,.2f}'.format(batch.po_total),
|
||||
}
|
||||
|
||||
def receiving_form(self):
|
||||
"""
|
||||
Workflow view for receiving items on a purchase batch.
|
||||
"""
|
||||
batch = self.get_instance()
|
||||
if batch.executed:
|
||||
return self.redirect(self.get_action_url('view', batch))
|
||||
|
||||
form = forms.SimpleForm(self.request, schema=ReceivingForm)
|
||||
if form.validate():
|
||||
assert form.data['mode'] == 'received' # TODO
|
||||
|
||||
product = form.data['product']
|
||||
rows = [row for row in batch.active_rows() if row.product is product]
|
||||
if rows:
|
||||
if len(rows) > 1:
|
||||
log.warning("found {} matching rows in batch {} for product: {}".format(
|
||||
len(rows), batch.id_str, product.upc.pretty()))
|
||||
row = rows[0]
|
||||
else:
|
||||
row = model.PurchaseBatchRow()
|
||||
row.product = product
|
||||
|
||||
if form.data['cases']:
|
||||
row.cases_received = (row.cases_received or 0) + form.data['cases']
|
||||
if form.data['units']:
|
||||
row.units_received = (row.units_received or 0) + form.data['units']
|
||||
|
||||
if not row.uuid:
|
||||
batch.add_row(row)
|
||||
self.handler.refresh_row(row)
|
||||
|
||||
self.request.session.flash("({}) {} cases, {} units: {} {}".format(
|
||||
form.data['mode'], form.data['cases'] or 0, form.data['units'] or 0,
|
||||
product.upc.pretty(), product))
|
||||
return self.redirect(self.request.current_route_url())
|
||||
|
||||
title = self.get_instance_title(batch)
|
||||
return self.render_to_response('receive_form', {
|
||||
'batch': batch,
|
||||
'instance': batch,
|
||||
'instance_title': title,
|
||||
'index_title': "{}: {}".format(self.get_model_title(), title),
|
||||
'index_url': self.get_action_url('view', batch),
|
||||
'vendor': batch.vendor,
|
||||
'form': forms.FormRenderer(form),
|
||||
})
|
||||
|
||||
def receiving_lookup(self):
|
||||
"""
|
||||
Try to locate a product by UPC, and validate it in the context of
|
||||
current batch, returning some data for client JS.
|
||||
"""
|
||||
batch = self.get_instance()
|
||||
if batch.executed:
|
||||
return {
|
||||
'error': "Current batch has already been executed",
|
||||
'redirect': self.get_action_url('view', batch),
|
||||
}
|
||||
data = None
|
||||
upc = self.request.GET.get('upc', '').strip()
|
||||
upc = re.sub(r'\D', '', upc)
|
||||
if upc:
|
||||
product = api.get_product_by_upc(Session(), upc)
|
||||
if not product:
|
||||
# Try again, assuming caller did not include check digit.
|
||||
upc = GPC(upc, calc_check_digit='upc')
|
||||
product = api.get_product_by_upc(Session(), upc)
|
||||
if product and (not product.deleted or self.request.has_perm('products.view_deleted')):
|
||||
data = {
|
||||
'uuid': product.uuid,
|
||||
'upc': unicode(product.upc),
|
||||
'upc_pretty': product.upc.pretty(),
|
||||
'full_description': product.full_description,
|
||||
'image_url': pod.get_image_url(self.rattail_config, product.upc),
|
||||
}
|
||||
cost = product.cost_for_vendor(batch.vendor)
|
||||
if cost:
|
||||
data['cost_found'] = True
|
||||
if int(cost.case_size) == cost.case_size:
|
||||
data['cost_case_size'] = int(cost.case_size)
|
||||
else:
|
||||
data['cost_case_size'] = '{:0.4f}'.format(cost.case_size)
|
||||
else:
|
||||
data['cost_found'] = False
|
||||
data['found_in_batch'] = product in [row.product for row in batch.active_rows()]
|
||||
|
||||
return {'product': data}
|
||||
|
||||
@classmethod
|
||||
def defaults(cls, config):
|
||||
route_prefix = cls.get_route_prefix()
|
||||
|
@ -595,7 +703,7 @@ class PurchaseBatchView(BatchMasterView):
|
|||
cls._batch_defaults(config)
|
||||
cls._defaults(config)
|
||||
|
||||
# order form
|
||||
# ordering form
|
||||
config.add_tailbone_permission(permission_prefix, '{}.order_form'.format(permission_prefix),
|
||||
"Edit new {} in Order Form mode".format(model_title))
|
||||
config.add_route('{}.order_form'.format(route_prefix), '{}/{{{}}}/order-form'.format(url_prefix, model_key))
|
||||
|
@ -605,6 +713,16 @@ class PurchaseBatchView(BatchMasterView):
|
|||
config.add_view(cls, attr='order_form_update', route_name='{}.order_form_update'.format(route_prefix),
|
||||
renderer='json', permission='{}.order_form'.format(permission_prefix))
|
||||
|
||||
# receiving form, lookup
|
||||
config.add_tailbone_permission(permission_prefix, '{}.receiving_form'.format(permission_prefix),
|
||||
"Edit 'receiving' {} in Receiving Form mode".format(model_title))
|
||||
config.add_route('{}.receiving_form'.format(route_prefix), '{}/{{{}}}/receiving-form'.format(url_prefix, model_key))
|
||||
config.add_view(cls, attr='receiving_form', route_name='{}.receiving_form'.format(route_prefix),
|
||||
permission='{}.receiving_form'.format(permission_prefix))
|
||||
config.add_route('{}.receiving_lookup'.format(route_prefix), '{}/{{{}}}/receiving-form/lookup'.format(url_prefix, model_key))
|
||||
config.add_view(cls, attr='receiving_lookup', route_name='{}.receiving_lookup'.format(route_prefix),
|
||||
renderer='json', permission='{}.receiving_form'.format(permission_prefix))
|
||||
|
||||
|
||||
def includeme(config):
|
||||
PurchaseBatchView.defaults(config)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue