Add basic "ordering worksheet" API
display-only for the moment, pending review/feedback
This commit is contained in:
parent
d8b9ae9ff1
commit
136d181363
|
@ -31,9 +31,12 @@ from __future__ import unicode_literals, absolute_import
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
|
from rattail.core import Object
|
||||||
from rattail.db import model
|
from rattail.db import model
|
||||||
from rattail.util import pretty_quantity
|
from rattail.util import pretty_quantity
|
||||||
|
|
||||||
|
from cornice import Service
|
||||||
|
|
||||||
from tailbone.api.batch import APIBatchView, APIBatchRowView
|
from tailbone.api.batch import APIBatchView, APIBatchRowView
|
||||||
|
|
||||||
|
|
||||||
|
@ -84,6 +87,126 @@ class OrderingBatchViews(APIBatchView):
|
||||||
batch = super(OrderingBatchViews, self).create_object(data)
|
batch = super(OrderingBatchViews, self).create_object(data)
|
||||||
return batch
|
return batch
|
||||||
|
|
||||||
|
def worksheet(self):
|
||||||
|
"""
|
||||||
|
Returns primary data for the Ordering Worksheet view.
|
||||||
|
"""
|
||||||
|
batch = self.get_object()
|
||||||
|
if batch.executed:
|
||||||
|
raise self.forbidden()
|
||||||
|
|
||||||
|
# TODO: much of the logic below was copied from the traditional master
|
||||||
|
# view for ordering batches. should maybe let them share it somehow?
|
||||||
|
|
||||||
|
# organize existing batch rows by product
|
||||||
|
order_items = {}
|
||||||
|
for row in batch.active_rows():
|
||||||
|
order_items[row.product_uuid] = row
|
||||||
|
|
||||||
|
# organize vendor catalog costs by dept / subdept
|
||||||
|
departments = {}
|
||||||
|
costs = self.handler.get_order_form_costs(self.Session(), batch.vendor)
|
||||||
|
costs = self.handler.sort_order_form_costs(costs)
|
||||||
|
costs = list(costs) # we must have a stable list for the rest of this
|
||||||
|
self.handler.decorate_order_form_costs(batch, costs)
|
||||||
|
for cost in costs:
|
||||||
|
|
||||||
|
department = cost.product.department
|
||||||
|
if department:
|
||||||
|
department_dict = departments.setdefault(department.uuid, {
|
||||||
|
'uuid': department.uuid,
|
||||||
|
'number': department.number,
|
||||||
|
'name': department.name,
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
if None not in departments:
|
||||||
|
departments[None] = {
|
||||||
|
'uuid': None,
|
||||||
|
'number': None,
|
||||||
|
'name': "",
|
||||||
|
}
|
||||||
|
department_dict = departments[None]
|
||||||
|
|
||||||
|
subdepartments = department_dict.setdefault('subdepartments', {})
|
||||||
|
|
||||||
|
subdepartment = cost.product.subdepartment
|
||||||
|
if subdepartment:
|
||||||
|
subdepartment_dict = subdepartments.setdefault(subdepartment.uuid, {
|
||||||
|
'uuid': subdepartment.uuid,
|
||||||
|
'number': subdepartment.number,
|
||||||
|
'name': subdepartment.name,
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
if None not in subdepartments:
|
||||||
|
subdepartments[None] = {
|
||||||
|
'uuid': None,
|
||||||
|
'number': None,
|
||||||
|
'name': "",
|
||||||
|
}
|
||||||
|
subdepartment_dict = subdepartments[None]
|
||||||
|
|
||||||
|
subdept_costs = subdepartment_dict.setdefault('costs', [])
|
||||||
|
product = cost.product
|
||||||
|
subdept_costs.append({
|
||||||
|
'uuid': cost.uuid,
|
||||||
|
'upc': six.text_type(product.upc),
|
||||||
|
'upc_pretty': product.upc.pretty() if product.upc else None,
|
||||||
|
'brand_name': product.brand.name if product.brand else None,
|
||||||
|
'description': product.description,
|
||||||
|
'size': product.size,
|
||||||
|
'case_size': cost.case_size,
|
||||||
|
'uom_display': "LB" if product.weighed else "EA",
|
||||||
|
'vendor_item_code': cost.code,
|
||||||
|
'preference': cost.preference,
|
||||||
|
'preferred': cost.preference == 1,
|
||||||
|
'unit_cost': cost.unit_cost,
|
||||||
|
'unit_cost_display': "${:0.2f}".format(cost.unit_cost) if cost.unit_cost is not None else "",
|
||||||
|
# TODO
|
||||||
|
# 'cases_ordered': None,
|
||||||
|
# 'units_ordered': None,
|
||||||
|
# 'po_total': None,
|
||||||
|
# 'po_total_display': None,
|
||||||
|
})
|
||||||
|
|
||||||
|
# sort the (sub)department groupings
|
||||||
|
sorted_departments = []
|
||||||
|
for dept in sorted(six.itervalues(departments), key=lambda d: d['name']):
|
||||||
|
dept['subdepartments'] = sorted(six.itervalues(dept['subdepartments']),
|
||||||
|
key=lambda s: s['name'])
|
||||||
|
sorted_departments.append(dept)
|
||||||
|
|
||||||
|
# fetch recent purchase history, sort/pad for template convenience
|
||||||
|
history = self.handler.get_order_form_history(batch, costs, 6)
|
||||||
|
for i in range(6 - len(history)):
|
||||||
|
history.append(None)
|
||||||
|
history = list(reversed(history))
|
||||||
|
|
||||||
|
return {
|
||||||
|
'batch': self.normalize(batch),
|
||||||
|
'departments': departments,
|
||||||
|
'sorted_departments': sorted_departments,
|
||||||
|
'history': history,
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def defaults(cls, config):
|
||||||
|
cls._defaults(config)
|
||||||
|
cls._batch_defaults(config)
|
||||||
|
cls._ordering_batch_defaults(config)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _ordering_batch_defaults(cls, config):
|
||||||
|
route_prefix = cls.get_route_prefix()
|
||||||
|
permission_prefix = cls.get_permission_prefix()
|
||||||
|
object_url_prefix = cls.get_object_url_prefix()
|
||||||
|
|
||||||
|
# worksheet
|
||||||
|
worksheet = Service(name='{}.worksheet'.format(route_prefix),
|
||||||
|
path='{}/{{uuid}}/worksheet'.format(object_url_prefix))
|
||||||
|
worksheet.add_view('GET', 'worksheet', klass=cls,
|
||||||
|
permission='{}.worksheet'.format(permission_prefix))
|
||||||
|
config.add_cornice_service(worksheet)
|
||||||
|
|
||||||
|
|
||||||
class OrderingBatchRowViews(APIBatchRowView):
|
class OrderingBatchRowViews(APIBatchRowView):
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue