Add "discarded" flag when receiving DMG/EXP products; add view for purchase credits

This commit is contained in:
Lance Edgar 2016-12-30 12:37:07 -06:00
parent 55973bf30a
commit e13e2cfaaf
3 changed files with 122 additions and 5 deletions

View file

@ -154,7 +154,28 @@
} }
$(this).button('disable').button('option', 'label', "Working..."); $(this).button('disable').button('option', 'label', "Working...");
$('#mode').val('damaged'); $('#mode').val('damaged');
$('#receiving-form').submit(); $('#damaged-dialog').dialog({
title: "Damaged Product",
modal: true,
width: '500px',
buttons: [
{
text: "OK",
click: function() {
$('#damaged-dialog').dialog('close');
$('#receiving-form #trash').val($('#damaged-dialog #trash').is(':checked') ? '1' : '');
$('#receiving-form').submit();
}
},
{
text: "Cancel",
click: function() {
$('#damaged').button('option', 'label', "Damaged").button('enable');
$('#damaged-dialog').dialog('close');
}
}
]
});
}); });
$('#expiration input[type="date"]').datepicker(); $('#expiration input[type="date"]').datepicker();
@ -166,8 +187,9 @@
$(this).button('disable').button('option', 'label', "Working..."); $(this).button('disable').button('option', 'label', "Working...");
$('#mode').val('expired'); $('#mode').val('expired');
$('#expiration').dialog({ $('#expiration').dialog({
title: "Expiration Date", title: "Expired / Short Date",
modal: true, modal: true,
width: '500px',
buttons: [ buttons: [
{ {
text: "OK", text: "OK",
@ -175,6 +197,7 @@
$('#expiration').dialog('close'); $('#expiration').dialog('close');
$('#receiving-form #expiration_date').val( $('#receiving-form #expiration_date').val(
$('#expiration input[type="date"]').val()); $('#expiration input[type="date"]').val());
$('#receiving-form #trash').val($('#expiration #trash').is(':checked') ? '1' : '');
$('#receiving-form').submit(); $('#receiving-form').submit();
} }
}, },
@ -280,6 +303,10 @@
}); });
</script> </script>
</%def>
<%def name="extra_styles()">
${parent.extra_styles()}
<style type="text/css"> <style type="text/css">
.product-info { .product-info {
@ -329,6 +356,7 @@
${form.csrf_token()} ${form.csrf_token()}
${h.hidden('mode')} ${h.hidden('mode')}
${h.hidden('expiration_date')} ${h.hidden('expiration_date')}
${h.hidden('trash')}
${h.hidden('ordered_product')} ${h.hidden('ordered_product')}
<div class="field-wrapper"> <div class="field-wrapper">
@ -412,14 +440,22 @@
<button type="button" id="received">Received</button> <button type="button" id="received">Received</button>
<button type="button" id="damaged">Damaged</button> <button type="button" id="damaged">Damaged</button>
<button type="button" id="expired">Expired</button> <button type="button" id="expired">Expired</button>
<button type="button" id="mispick">Mispick</button> <!-- <button type="button" id="mispick">Mispick</button> -->
</div> </div>
${form.end()} ${form.end()}
</div> </div>
<div id="damaged-dialog" style="display: none;">
<div class="field-wrapper trash">${h.checkbox('trash', label="Product will be discarded and cannot be returned", checked=False)}</div>
</div>
<div id="expiration" style="display: none;"> <div id="expiration" style="display: none;">
${h.text('expiration-date', type='date')} <div class="field-wrapper expiration-date">
<label for="expiration-date">Expiration Date</label>
<div class="field">${h.text('expiration-date', type='date')}</div>
</div>
<div class="field-wrapper trash">${h.checkbox('trash', label="Product will be discarded and cannot be returned", checked=False)}</div>
</div> </div>
<div id="mispick-dialog" style="display: none;"> <div id="mispick-dialog" style="display: none;">

View file

@ -64,6 +64,7 @@ class ReceivingForm(forms.Schema):
cases = fe.validators.Number() cases = fe.validators.Number()
units = fe.validators.Number() units = fe.validators.Number()
expiration_date = fe.validators.DateValidator() expiration_date = fe.validators.DateValidator()
trash = fe.validators.Bool()
ordered_product = forms.validators.ValidProduct() ordered_product = forms.validators.ValidProduct()
@ -685,7 +686,7 @@ class PurchaseBatchView(BatchMasterView):
'batch_po_total': '${:0,.2f}'.format(batch.po_total), 'batch_po_total': '${:0,.2f}'.format(batch.po_total),
} }
def attach_credit(self, row, credit_type, cases, units, expiration_date=None, mispick_product=None): def attach_credit(self, row, credit_type, cases, units, expiration_date=None, discarded=None, mispick_product=None):
batch = row.batch batch = row.batch
credit = model.PurchaseBatchCredit() credit = model.PurchaseBatchCredit()
credit.credit_type = credit_type credit.credit_type = credit_type
@ -710,6 +711,7 @@ class PurchaseBatchView(BatchMasterView):
credit.invoice_case_cost = row.invoice_case_cost credit.invoice_case_cost = row.invoice_case_cost
credit.invoice_unit_cost = row.invoice_unit_cost credit.invoice_unit_cost = row.invoice_unit_cost
credit.invoice_total = row.invoice_total credit.invoice_total = row.invoice_total
credit.product_discarded = discarded
if credit_type == 'expired': if credit_type == 'expired':
credit.expiration_date = expiration_date credit.expiration_date = expiration_date
elif credit_type == 'mispick' and mispick_product: elif credit_type == 'mispick' and mispick_product:
@ -768,6 +770,7 @@ class PurchaseBatchView(BatchMasterView):
if mode in ('damaged', 'expired', 'mispick'): if mode in ('damaged', 'expired', 'mispick'):
self.attach_credit(row, mode, cases, units, self.attach_credit(row, mode, cases, units,
expiration_date=form.data['expiration_date'], expiration_date=form.data['expiration_date'],
discarded=form.data['trash'],
mispick_product=shipped_product) mispick_product=shipped_product)
self.handler.refresh_row(row) self.handler.refresh_row(row)

View file

@ -0,0 +1,78 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2016 Lance Edgar
#
# This file is part of Rattail.
#
# Rattail is free software: you can redistribute it and/or modify it under the
# terms of the GNU Affero General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
# more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Rattail. If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
"""
Views for "true" purchase credits
"""
from __future__ import unicode_literals, absolute_import
from rattail.db import model
from tailbone import forms
from tailbone.views import MasterView
class PurchaseCreditView(MasterView):
"""
Master view for purchase credits
"""
model_class = model.PurchaseCredit
route_prefix = 'purchases.credits'
url_prefix = '/purchases/credits'
creatable = False
editable = False
def _preconfigure_grid(self, g):
g.joiners['vendor'] = lambda q: q.outerjoin(model.Vendor)
g.sorters['vendor'] = g.make_sorter(model.Vendor.name)
g.default_sortkey = 'date_received'
g.default_sortdir = 'desc'
g.upc.set(label="UPC")
g.brand_name.set(label="Brand")
g.cases_shorted.set(label="Cases", renderer=forms.renderers.QuantityFieldRenderer)
g.units_shorted.set(label="Units", renderer=forms.renderers.QuantityFieldRenderer)
g.credit_type.set(label="Type")
g.date_received.set(label="Date")
def configure_grid(self, g):
g.configure(
include=[
g.vendor,
g.upc,
g.brand_name,
g.description,
g.size,
g.cases_shorted,
g.units_shorted,
g.credit_type,
g.date_received,
g.status,
],
readonly=True)
def includeme(config):
PurchaseCreditView.defaults(config)