Add support for more cases + units, more vendor fields, for new purchase batches

This commit is contained in:
Lance Edgar 2016-11-11 01:56:37 -06:00
parent 1f9a27a7ae
commit 11b4cf9616
3 changed files with 97 additions and 17 deletions

View file

@ -26,7 +26,9 @@ Vendor Field Renderers
from __future__ import unicode_literals, absolute_import from __future__ import unicode_literals, absolute_import
from .common import AutocompleteFieldRenderer from webhelpers.html import tags
from tailbone.forms.renderers.common import AutocompleteFieldRenderer
class VendorFieldRenderer(AutocompleteFieldRenderer): class VendorFieldRenderer(AutocompleteFieldRenderer):
@ -34,3 +36,9 @@ class VendorFieldRenderer(AutocompleteFieldRenderer):
Renderer for :class:`rattail.db.model.Vendor` instance fields. Renderer for :class:`rattail.db.model.Vendor` instance fields.
""" """
service_route = 'vendors.autocomplete' service_route = 'vendors.autocomplete'
def render_readonly(self, **kwargs):
vendor = self.raw_value
if not vendor:
return ''
return tags.link_to(vendor, self.request.route_url('vendors.view', uuid=vendor.uuid))

View file

@ -15,17 +15,19 @@
} }
if (event.which == 13) { if (event.which == 13) {
var input = $(this); var input = $(this);
var row = input.parents('tr:first'); var row = $(this).parents('tr:first');
var data = { var data = {
product_uuid: row.data('uuid'), product_uuid: row.data('uuid'),
cases_ordered: input.val() || '0' cases_ordered: row.find('input[name^="cases_ordered_"]').val() || '0',
units_ordered: row.find('input[name^="units_ordered_"]').val() || '0'
}; };
$.post('${url('purchases.batch.order_form_update', uuid=batch.uuid)}', data, function(data) { $.post('${url('purchases.batch.order_form_update', uuid=batch.uuid)}', data, function(data) {
if (data.error) { if (data.error) {
alert(data.error); alert(data.error);
} else { } else {
input.val(data.row_cases_ordered); row.find('input[name^="cases_ordered_"]').val(data.row_cases_ordered);
row.find('td:eq(14)').html(data.row_po_total); row.find('input[name^="units_ordered_"]').val(data.row_units_ordered);
row.find('td:eq(15)').html(data.row_po_total);
$('.po-total .field').html(data.batch_po_total); $('.po-total .field').html(data.batch_po_total);
} }
}); });
@ -98,9 +100,31 @@
<div class="field-wrapper"> <div class="field-wrapper">
<label>Vendor</label> <label>Vendor</label>
<div class="field">${vendor}</div> <div class="field">${h.link_to(vendor, url('vendors.view', uuid=vendor.uuid))}</div>
</div> </div>
<div class="field-wrapper">
<label>Vendor Email</label>
<div class="field">${vendor.email or ''}</div>
</div>
<div class="field-wrapper">
<label>Vendor Fax</label>
<div class="field">${vendor.fax_number or ''}</div>
</div>
<div class="field-wrapper">
<label>Vendor Contact</label>
<div class="field">${vendor.contact or ''}</div>
</div>
<div class="field-wrapper">
<label>Vendor Phone</label>
<div class="field">${vendor.phone or ''}</div>
</div>
${self.extra_vendor_fields()}
<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>
@ -111,7 +135,7 @@
<div class="newgrid"> <div class="newgrid">
<table class="order-form"> <table class="order-form">
<% column_count = 15 + int(capture(self.extra_count)) %> <% column_count = 16 + 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>
@ -132,7 +156,14 @@
% for data in history.itervalues(): % for data in history.itervalues():
<th>${data['purchase'].date_ordered.strftime('%m/%d') if data else ''}</th> <th>${data['purchase'].date_ordered.strftime('%m/%d') if data else ''}</th>
% endfor % endfor
<th>${batch.date_ordered.strftime('%m/%d')}</th> <th>
${batch.date_ordered.strftime('%m/%d')}<br />
Cases
</th>
<th>
${batch.date_ordered.strftime('%m/%d')}<br />
Units
</th>
<th>PO Total</th> <th>PO Total</th>
${self.extra_th()} ${self.extra_th()}
</tr> </tr>
@ -150,13 +181,17 @@
% for data in history.itervalues(): % for data in history.itervalues():
<td class="scratch_pad"> <td class="scratch_pad">
% if data and cost.product_uuid in data['items']: % if data and cost.product_uuid in data['items']:
${int(data['items'][cost.product_uuid].cases_ordered or 0) or ''} ${'{} / {}'.format(int(data['items'][cost.product_uuid].cases_ordered or 0), int(data['items'][cost.product_uuid].units_ordered or 0))}
## ${int(data['items'][cost.product_uuid].cases_ordered or 0) or ''}
% endif % endif
</td> </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="current-order">
${h.text('units_ordered_{}'.format(cost.uuid), value=int(cost._batchrow.units_ordered) if cost._batchrow else None)}
</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)} ${self.extra_td(cost)}
</tr> </tr>
@ -168,6 +203,8 @@
</div> </div>
<%def name="extra_vendor_fields()"></%def>
<%def name="extra_count()">0</%def> <%def name="extra_count()">0</%def>
<%def name="extra_th()"></%def> <%def name="extra_th()"></%def>

View file

@ -96,12 +96,35 @@ class PurchaseBatchView(BatchMasterView):
fs.po_number.set(label="PO Number") fs.po_number.set(label="PO Number")
fs.po_total.set(label="PO Total", readonly=True) fs.po_total.set(label="PO Total", readonly=True)
fs.append(fa.Field('vendor_email', readonly=True,
value=lambda b: b.vendor.email.address if b.vendor.email else None))
fs.append(fa.Field('vendor_fax', readonly=True,
value=self.get_vendor_fax_number))
fs.append(fa.Field('vendor_contact', readonly=True,
value=lambda b: b.vendor.contact or None))
fs.append(fa.Field('vendor_phone', readonly=True,
value=self.get_vendor_phone_number))
def get_vendor_phone_number(self, batch):
for phone in batch.vendor.phones:
if phone.type == 'Voice':
return phone.number
def get_vendor_fax_number(self, batch):
for phone in batch.vendor.phones:
if phone.type == 'Fax':
return phone.number
def configure_fieldset(self, fs): def configure_fieldset(self, fs):
fs.configure( fs.configure(
include=[ include=[
fs.id, fs.id,
fs.store, fs.store,
fs.vendor, fs.vendor,
fs.vendor_email,
fs.vendor_fax,
fs.vendor_contact,
fs.vendor_phone,
fs.buyer, fs.buyer,
fs.date_ordered, fs.date_ordered,
fs.po_number, fs.po_number,
@ -116,6 +139,10 @@ class PurchaseBatchView(BatchMasterView):
if self.creating: if self.creating:
del fs.po_total del fs.po_total
del fs.complete del fs.complete
del fs.vendor_email
del fs.vendor_fax
del fs.vendor_phone
del fs.vendor_contact
# default store may be configured # default store may be configured
store = self.rattail_config.get('rattail', 'store') store = self.rattail_config.get('rattail', 'store')
@ -367,10 +394,15 @@ class PurchaseBatchView(BatchMasterView):
""" """
batch = self.get_instance() batch = self.get_instance()
quantity = self.request.POST.get('cases_ordered') cases_ordered = self.request.POST.get('cases_ordered', '0')
if not quantity or not quantity.isdigit(): if not cases_ordered or not cases_ordered.isdigit():
return {'error': "Invalid quantity: {}".format(quantity)} return {'error': "Invalid value for cases ordered: {}".format(cases_ordered)}
quantity = int(quantity) cases_ordered = int(cases_ordered)
units_ordered = self.request.POST.get('units_ordered', '0')
if not units_ordered or not units_ordered.isdigit():
return {'error': "Invalid value for units ordered: {}".format(units_ordered)}
units_ordered = int(units_ordered)
uuid = self.request.POST.get('product_uuid') uuid = self.request.POST.get('product_uuid')
product = Session.query(model.Product).get(uuid) if uuid else None product = Session.query(model.Product).get(uuid) if uuid else None
@ -383,23 +415,26 @@ class PurchaseBatchView(BatchMasterView):
row = rows[0] row = rows[0]
if row.po_total and not row.removed: if row.po_total and not row.removed:
batch.po_total -= row.po_total batch.po_total -= row.po_total
if quantity: if cases_ordered or units_ordered:
row.cases_ordered = quantity row.cases_ordered = cases_ordered
row.units_ordered = units_ordered
row.removed = False row.removed = False
self.handler.refresh_row(row) self.handler.refresh_row(row)
else: else:
row.removed = True row.removed = True
elif quantity: elif cases_ordered or units_ordered:
row = model.PurchaseBatchRow() row = model.PurchaseBatchRow()
row.sequence = max([0] + [r.sequence for r in batch.data_rows]) + 1 row.sequence = max([0] + [r.sequence for r in batch.data_rows]) + 1
row.product = product row.product = product
batch.data_rows.append(row) batch.data_rows.append(row)
row.cases_ordered = quantity row.cases_ordered = cases_ordered
row.units_ordered = units_ordered
self.handler.refresh_row(row) self.handler.refresh_row(row)
return { return {
'row_cases_ordered': '' if row.removed else int(row.cases_ordered), 'row_cases_ordered': '' if row.removed else int(row.cases_ordered),
'row_units_ordered': '' if row.removed else int(row.units_ordered),
'row_po_total': '' if row.removed else '${:0,.2f}'.format(row.po_total), 'row_po_total': '' if row.removed else '${:0,.2f}'.format(row.po_total),
'batch_po_total': '${:0,.2f}'.format(batch.po_total), 'batch_po_total': '${:0,.2f}'.format(batch.po_total),
} }