diff --git a/tailbone/templates/purchases/batches/order_form.mako b/tailbone/templates/purchases/batches/order_form.mako index 93ce95b6..eb09b2e5 100644 --- a/tailbone/templates/purchases/batches/order_form.mako +++ b/tailbone/templates/purchases/batches/order_form.mako @@ -61,7 +61,8 @@ .order-form td.upc, .order-form td.case-qty, .order-form td.code, - .order-form td.preferred { + .order-form td.preferred, + .order-form td.scratch_pad { text-align: center; } @@ -100,11 +101,6 @@
${vendor}
-
- -
${batch.date_ordered}
-
-
$${'{:0,.2f}'.format(batch.po_total or 0)}
@@ -115,14 +111,15 @@
+ <% column_count = 22 + int(capture(self.extra_count)) %> % for department in sorted(departments.itervalues(), key=lambda d: d.name if d else ''): - + % for subdepartment in sorted(department._order_subdepartments.itervalues(), key=lambda s: s.name if s else ''): - + @@ -132,8 +129,12 @@ - + % for data in history.itervalues(): + + % endfor + + ${self.extra_th()} @@ -146,13 +147,18 @@ - % for i in range(6): - + % for data in history.itervalues(): + % endfor + ${self.extra_td(cost)} % endfor @@ -160,3 +166,10 @@ % endfor
Department:  ${department.number} ${department.name}Department ${department.number} ${department.name}
Subdepartment:  ${subdepartment.number} ${subdepartment.name}Subdepartment ${subdepartment.number} ${subdepartment.name}
UPCVend. Code Pref. Unit Cost ${data['purchase'].date_ordered.strftime('%m/%d') if data else ''}${batch.date_ordered.strftime('%m/%d')} PO Total
${cost.code or ''} ${'X' if cost.preference == 1 else ''} $${'{:0.2f}'.format(cost.unit_cost)}         + % if data and cost.product_uuid in data['items']: + ${int(data['items'][cost.product_uuid].cases_ordered or 0) or ''} + % endif + ${h.text('cases_ordered_{}'.format(cost.uuid), value=int(cost._batchrow.cases_ordered) if cost._batchrow else None)} ${'${:0,.2f}'.format(cost._batchrow.po_total) if cost._batchrow else ''}
+ + +<%def name="extra_count()">0 + +<%def name="extra_th()"> + +<%def name="extra_td(cost)"> diff --git a/tailbone/views/purchases/batch.py b/tailbone/views/purchases/batch.py index b876c7e1..989a65d9 100644 --- a/tailbone/views/purchases/batch.py +++ b/tailbone/views/purchases/batch.py @@ -26,11 +26,15 @@ Views for purchase order batches from __future__ import unicode_literals, absolute_import +from sqlalchemy import orm + +from rattail import enum from rattail.db import model, api from rattail.gpc import GPC from rattail.db.batch.purchase.handler import PurchaseBatchHandler from rattail.time import localtime from rattail.core import Object +from rattail.util import OrderedDict import formalchemy as fa @@ -271,14 +275,6 @@ class PurchaseBatchView(BatchMasterView): batch = self.get_instance() if batch.executed: return self.redirect(self.get_action_url('view', batch)) - vendor = batch.vendor - costs = Session.query(model.ProductCost)\ - .join(model.Product)\ - .outerjoin(model.Brand)\ - .filter(model.ProductCost.vendor == vendor)\ - .order_by(model.Brand.name, - model.Product.description, - model.Product.size) # organize existing batch rows by product order_items = {} @@ -286,8 +282,12 @@ class PurchaseBatchView(BatchMasterView): if not row.removed: order_items[row.product_uuid] = row - # organize product costs by dept / subdept + # organize vendor catalog costs by dept / subdept departments = {} + costs = self.get_order_form_costs(batch.vendor)\ + .order_by(model.Brand.name, + model.Product.description, + model.Product.size) for cost in costs: department = cost.product.department @@ -318,6 +318,27 @@ class PurchaseBatchView(BatchMasterView): subdept_costs.append(cost) cost._batchrow = order_items.get(cost.product_uuid) + # do anything else needed to satisfy template display requirements etc. + self.decorate_order_form_cost(cost) + + # fetch last 6 purchases for this vendor, organize line items by product + history = OrderedDict() + purchases = Session.query(model.Purchase)\ + .filter(model.Purchase.vendor == batch.vendor)\ + .filter(model.Purchase.status >= enum.PURCHASE_STATUS_ORDERED)\ + .order_by(model.Purchase.date_ordered.desc(), model.Purchase.created.desc())\ + .options(orm.joinedload(model.Purchase.items))[:6] + for purchase in purchases[:6]: + items = {} + for item in purchase.items: + items[item.product_uuid] = item + history[purchase.uuid] = {'purchase': purchase, 'items': items} + + # reverse sorting and pad history as needed, for template convenience + for i in range(6 - len(history)): + history[i] = None + history = OrderedDict([(i, v) for i, v in enumerate(reversed(list(history.itervalues())))]) + title = self.get_instance_title(batch) return self.render_to_response('order_form', { 'batch': batch, @@ -325,11 +346,21 @@ class PurchaseBatchView(BatchMasterView): 'instance_title': title, 'index_title': "{}: {}".format(self.get_model_title(), title), 'index_url': self.get_action_url('view', batch), - 'vendor': vendor, + 'vendor': batch.vendor, 'departments': departments, + 'history': history, 'get_upc': lambda p: p.upc.pretty() if p.upc else '', }) + def get_order_form_costs(self, vendor): + return Session.query(model.ProductCost)\ + .join(model.Product)\ + .outerjoin(model.Brand)\ + .filter(model.ProductCost.vendor == vendor) + + def decorate_order_form_cost(self, cost): + pass + def order_form_update(self): """ Handles AJAX requests to update current batch, from Order Form view.