Add historical amounts to new purchase Order Form, allow extra columns etc.

This commit is contained in:
Lance Edgar 2016-11-08 22:45:58 -06:00
parent bf5808d517
commit da5c040aeb
2 changed files with 65 additions and 21 deletions

View file

@ -61,7 +61,8 @@
.order-form td.upc, .order-form td.upc,
.order-form td.case-qty, .order-form td.case-qty,
.order-form td.code, .order-form td.code,
.order-form td.preferred { .order-form td.preferred,
.order-form td.scratch_pad {
text-align: center; text-align: center;
} }
@ -100,11 +101,6 @@
<div class="field">${vendor}</div> <div class="field">${vendor}</div>
</div> </div>
<div class="field-wrapper">
<label>Order Date</label>
<div class="field">${batch.date_ordered}</div>
</div>
<div class="field-wrapper po-total"> <div class="field-wrapper po-total">
<label>PO Total</label> <label>PO Total</label>
<div class="field">$${'{:0,.2f}'.format(batch.po_total or 0)}</div> <div class="field">$${'{:0,.2f}'.format(batch.po_total or 0)}</div>
@ -115,14 +111,15 @@
<div class="newgrid"> <div class="newgrid">
<table class="order-form"> <table class="order-form">
<% column_count = 22 + int(capture(self.extra_count)) %>
% for department in sorted(departments.itervalues(), key=lambda d: d.name if d else ''): % for department in sorted(departments.itervalues(), key=lambda d: d.name if d else ''):
<thead> <thead>
<tr> <tr>
<th class="department" colspan="22">Department:&nbsp; ${department.number} ${department.name}</th> <th class="department" colspan="${column_count}">Department ${department.number} ${department.name}</th>
</tr> </tr>
% for subdepartment in sorted(department._order_subdepartments.itervalues(), key=lambda s: s.name if s else ''): % for subdepartment in sorted(department._order_subdepartments.itervalues(), key=lambda s: s.name if s else ''):
<tr> <tr>
<th class="subdepartment" colspan="22">Subdepartment:&nbsp; ${subdepartment.number} ${subdepartment.name}</th> <th class="subdepartment" colspan="${column_count}">Subdepartment ${subdepartment.number} ${subdepartment.name}</th>
</tr> </tr>
<tr> <tr>
<th>UPC</th> <th>UPC</th>
@ -132,8 +129,12 @@
<th>Vend. Code</th> <th>Vend. Code</th>
<th>Pref.</th> <th>Pref.</th>
<th>Unit Cost</th> <th>Unit Cost</th>
<th colspan="7">&nbsp;</th> % for data in history.itervalues():
<th>${data['purchase'].date_ordered.strftime('%m/%d') if data else ''}</th>
% endfor
<th>${batch.date_ordered.strftime('%m/%d')}</th>
<th>PO Total</th> <th>PO Total</th>
${self.extra_th()}
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -146,13 +147,18 @@
<td class="code">${cost.code or ''}</td> <td class="code">${cost.code or ''}</td>
<td class="preferred">${'X' if cost.preference == 1 else ''}</td> <td class="preferred">${'X' if cost.preference == 1 else ''}</td>
<td class="unit-cost">$${'{:0.2f}'.format(cost.unit_cost)}</td> <td class="unit-cost">$${'{:0.2f}'.format(cost.unit_cost)}</td>
% for i in range(6): % for data in history.itervalues():
<td class="scratch_pad">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td> <td class="scratch_pad">
% if data and cost.product_uuid in data['items']:
${int(data['items'][cost.product_uuid].cases_ordered or 0) or ''}
% endif
</td>
% endfor % endfor
<td class="current-order"> <td class="current-order">
${h.text('cases_ordered_{}'.format(cost.uuid), value=int(cost._batchrow.cases_ordered) if cost._batchrow else None)} ${h.text('cases_ordered_{}'.format(cost.uuid), value=int(cost._batchrow.cases_ordered) if cost._batchrow else None)}
</td> </td>
<td class="po-total">${'${:0,.2f}'.format(cost._batchrow.po_total) if cost._batchrow else ''}</td> <td class="po-total">${'${:0,.2f}'.format(cost._batchrow.po_total) if cost._batchrow else ''}</td>
${self.extra_td(cost)}
</tr> </tr>
% endfor % endfor
</tbody> </tbody>
@ -160,3 +166,10 @@
% endfor % endfor
</table> </table>
</div> </div>
<%def name="extra_count()">0</%def>
<%def name="extra_th()"></%def>
<%def name="extra_td(cost)"></%def>

View file

@ -26,11 +26,15 @@ Views for purchase order batches
from __future__ import unicode_literals, absolute_import from __future__ import unicode_literals, absolute_import
from sqlalchemy import orm
from rattail import enum
from rattail.db import model, api from rattail.db import model, api
from rattail.gpc import GPC from rattail.gpc import GPC
from rattail.db.batch.purchase.handler import PurchaseBatchHandler from rattail.db.batch.purchase.handler import PurchaseBatchHandler
from rattail.time import localtime from rattail.time import localtime
from rattail.core import Object from rattail.core import Object
from rattail.util import OrderedDict
import formalchemy as fa import formalchemy as fa
@ -271,14 +275,6 @@ class PurchaseBatchView(BatchMasterView):
batch = self.get_instance() batch = self.get_instance()
if batch.executed: if batch.executed:
return self.redirect(self.get_action_url('view', batch)) 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 # organize existing batch rows by product
order_items = {} order_items = {}
@ -286,8 +282,12 @@ class PurchaseBatchView(BatchMasterView):
if not row.removed: if not row.removed:
order_items[row.product_uuid] = row order_items[row.product_uuid] = row
# organize product costs by dept / subdept # organize vendor catalog costs by dept / subdept
departments = {} departments = {}
costs = self.get_order_form_costs(batch.vendor)\
.order_by(model.Brand.name,
model.Product.description,
model.Product.size)
for cost in costs: for cost in costs:
department = cost.product.department department = cost.product.department
@ -318,6 +318,27 @@ class PurchaseBatchView(BatchMasterView):
subdept_costs.append(cost) subdept_costs.append(cost)
cost._batchrow = order_items.get(cost.product_uuid) 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) title = self.get_instance_title(batch)
return self.render_to_response('order_form', { return self.render_to_response('order_form', {
'batch': batch, 'batch': batch,
@ -325,11 +346,21 @@ class PurchaseBatchView(BatchMasterView):
'instance_title': title, 'instance_title': title,
'index_title': "{}: {}".format(self.get_model_title(), title), 'index_title': "{}: {}".format(self.get_model_title(), title),
'index_url': self.get_action_url('view', batch), 'index_url': self.get_action_url('view', batch),
'vendor': vendor, 'vendor': batch.vendor,
'departments': departments, 'departments': departments,
'history': history,
'get_upc': lambda p: p.upc.pretty() if p.upc else '', '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): def order_form_update(self):
""" """
Handles AJAX requests to update current batch, from Order Form view. Handles AJAX requests to update current batch, from Order Form view.