Add historical amounts to new purchase Order Form, allow extra columns etc.
This commit is contained in:
parent
bf5808d517
commit
da5c040aeb
|
@ -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: ${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: ${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"> </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"> </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>
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in a new issue