Add initial support for mispicks / attaching credits for receiving batch
This commit is contained in:
parent
b3010465b6
commit
839d3957dd
|
@ -8,11 +8,26 @@
|
||||||
${h.javascript_link(request.static_url('tailbone:static/js/numeric.js'))}
|
${h.javascript_link(request.static_url('tailbone:static/js/numeric.js'))}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
function assert_quantity() {
|
||||||
|
if ($('#cases').val() && parseFloat($('#cases').val())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ($('#units').val() && parseFloat($('#units').val())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
alert("Please provide case and/or unit quantity");
|
||||||
|
$('#cases').select().focus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
function invalid_product(msg) {
|
function invalid_product(msg) {
|
||||||
$('#product-info p').text(msg);
|
$('#received-product-info p').text(msg);
|
||||||
$('#product-info img').hide();
|
$('#received-product-info img').hide();
|
||||||
$('#product-info .rogue-item-warning').hide();
|
$('#received-product-info .rogue-item-warning').hide();
|
||||||
$('#product-textbox').focus().select();
|
$('#product-textbox').focus().select();
|
||||||
|
$('.field-wrapper.cases input').prop('disabled', true);
|
||||||
|
$('.field-wrapper.units input').prop('disabled', true);
|
||||||
|
$('.buttons button').button('disable');
|
||||||
}
|
}
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
|
@ -24,9 +39,12 @@
|
||||||
}
|
}
|
||||||
if (key_modifies(event)) {
|
if (key_modifies(event)) {
|
||||||
$('#product').val('');
|
$('#product').val('');
|
||||||
$('#product-info p').html(' ');
|
$('#received-product-info p').html("please ENTER a scancode");
|
||||||
$('#product-info img').hide();
|
$('#received-product-info img').hide();
|
||||||
$('#product-info .rogue-item-warning').hide();
|
$('#received-product-info .rogue-item-warning').hide();
|
||||||
|
$('.field-wrapper.cases input').prop('disabled', true);
|
||||||
|
$('.field-wrapper.units input').prop('disabled', true);
|
||||||
|
$('.buttons button').button('disable');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (event.which == 13) {
|
if (event.which == 13) {
|
||||||
|
@ -41,18 +59,17 @@
|
||||||
}
|
}
|
||||||
} else if (data.product) {
|
} else if (data.product) {
|
||||||
input.val(data.product.upc_pretty);
|
input.val(data.product.upc_pretty);
|
||||||
if (data.product.cost_found) {
|
$('#product').val(data.product.uuid);
|
||||||
$('#product').val(data.product.uuid);
|
$('#received-product-info p').text(data.product.full_description);
|
||||||
$('#product-info p').text(data.product.full_description);
|
$('#received-product-info img').attr('src', data.product.image_url).show();
|
||||||
$('#product-info img').attr('src', data.product.image_url).show();
|
$('#received-product-info .rogue-item-warning').hide();
|
||||||
$('#product-info .rogue-item-warning').hide();
|
if (! data.product.found_in_batch) {
|
||||||
$('#cases').focus().select();
|
$('#received-product-info .rogue-item-warning').show();
|
||||||
if (! data.product.found_in_batch) {
|
|
||||||
$('#product-info .rogue-item-warning').show();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
invalid_product('cost not found for ' + data.product.full_description);
|
|
||||||
}
|
}
|
||||||
|
$('.field-wrapper.cases input').prop('disabled', false);
|
||||||
|
$('.field-wrapper.units input').prop('disabled', false);
|
||||||
|
$('.buttons button').button('enable');
|
||||||
|
$('#cases').focus().select();
|
||||||
} else {
|
} else {
|
||||||
invalid_product('product not found');
|
invalid_product('product not found');
|
||||||
}
|
}
|
||||||
|
@ -61,49 +78,174 @@
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#product-textbox').focus();
|
|
||||||
|
|
||||||
$('#received').click(function() {
|
$('#received').click(function() {
|
||||||
|
if (! assert_quantity()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
$(this).button('disable').button('option', 'label', "Working...");
|
$(this).button('disable').button('option', 'label', "Working...");
|
||||||
$('#mode').val('received');
|
$('#mode').val('received');
|
||||||
$('#receiving-form').submit();
|
$('#receiving-form').submit();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#damaged').click(function() {
|
$('#damaged').click(function() {
|
||||||
|
if (! assert_quantity()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
$(this).button('disable').button('option', 'label', "Working...");
|
$(this).button('disable').button('option', 'label', "Working...");
|
||||||
$('#mode').val('damaged');
|
$('#mode').val('damaged');
|
||||||
$('#receiving-form').submit();
|
$('#receiving-form').submit();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#expiration input[type="date"]').datepicker();
|
||||||
|
|
||||||
$('#expired').click(function() {
|
$('#expired').click(function() {
|
||||||
|
if (! assert_quantity()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
$(this).button('disable').button('option', 'label', "Working...");
|
$(this).button('disable').button('option', 'label', "Working...");
|
||||||
$('#mode').val('expired');
|
$('#mode').val('expired');
|
||||||
$('#receiving-form').submit();
|
$('#expiration').dialog({
|
||||||
|
title: "Expiration Date",
|
||||||
|
modal: true,
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
text: "OK",
|
||||||
|
click: function() {
|
||||||
|
$('#expiration').dialog('close');
|
||||||
|
$('#receiving-form #expiration_date').val(
|
||||||
|
$('#expiration input[type="date"]').val());
|
||||||
|
$('#receiving-form').submit();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Cancel",
|
||||||
|
click: function() {
|
||||||
|
$('#expired').button('option', 'label', "Expired").button('enable');
|
||||||
|
$('#expiration').dialog('close');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#mispick').click(function() {
|
||||||
|
if (! assert_quantity()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$(this).button('disable').button('option', 'label', "Working...");
|
||||||
|
$('#ordered-product').val('');
|
||||||
|
$('#ordered-product-textbox').val('');
|
||||||
|
$('#ordered-product-info p').html("please ENTER a scancode");
|
||||||
|
$('#ordered-product-info img').hide();
|
||||||
|
$('#mispick-dialog').dialog({
|
||||||
|
title: "Mispick - Ordered Product",
|
||||||
|
modal: true,
|
||||||
|
width: 400,
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
text: "OK",
|
||||||
|
click: function() {
|
||||||
|
if ($('#ordered-product-info .warning').is(':visible')) {
|
||||||
|
alert("You must choose a product which was ordered.");
|
||||||
|
$('#ordered-product-textbox').select().focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$('#mispick-dialog').dialog('close');
|
||||||
|
$('#mode').val('mispick');
|
||||||
|
$('#receiving-form').submit();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Cancel",
|
||||||
|
click: function() {
|
||||||
|
$('#mispick').button('option', 'label', "Mispick").button('enable');
|
||||||
|
$('#mispick-dialog').dialog('close');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#ordered-product-textbox').keydown(function(event) {
|
||||||
|
|
||||||
|
if (key_allowed(event)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (key_modifies(event)) {
|
||||||
|
$('#ordered_product').val('');
|
||||||
|
$('#ordered-product-info p').html("please ENTER a scancode");
|
||||||
|
$('#ordered-product-info img').hide();
|
||||||
|
$('#ordered-product-info .warning').hide();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (event.which == 13) {
|
||||||
|
var input = $(this);
|
||||||
|
var data = {upc: input.val()};
|
||||||
|
$.get('${url('purchases.batch.receiving_lookup', uuid=batch.uuid)}', data, function(data) {
|
||||||
|
if (data.error) {
|
||||||
|
alert(data.error);
|
||||||
|
if (data.redirect) {
|
||||||
|
$('#mispick-dialog').mask("Redirecting...");
|
||||||
|
location.href = data.redirect;
|
||||||
|
}
|
||||||
|
} else if (data.product) {
|
||||||
|
input.val(data.product.upc_pretty);
|
||||||
|
$('#ordered_product').val(data.product.uuid);
|
||||||
|
$('#ordered-product-info p').text(data.product.full_description);
|
||||||
|
$('#ordered-product-info img').attr('src', data.product.image_url).show();
|
||||||
|
if (data.product.found_in_batch) {
|
||||||
|
$('#ordered-product-info .warning').hide();
|
||||||
|
} else {
|
||||||
|
$('#ordered-product-info .warning').show();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$('#ordered-product-info p').text("product not found");
|
||||||
|
$('#ordered-product-info img').hide();
|
||||||
|
$('#ordered-product-info .warning').hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#receiving-form').submit(function() {
|
$('#receiving-form').submit(function() {
|
||||||
$(this).mask("Working...");
|
$(this).mask("Working...");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#product-textbox').focus();
|
||||||
|
$('.field-wrapper.cases input').prop('disabled', true);
|
||||||
|
$('.field-wrapper.units input').prop('disabled', true);
|
||||||
|
$('.buttons button').button('disable');
|
||||||
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
|
|
||||||
#product-info {
|
.product-info {
|
||||||
margin-top: 0.5em;
|
margin-top: 0.5em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#product-info p {
|
.product-info p {
|
||||||
margin-left: 0.5em;
|
margin-left: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#product-info .img-wrapper {
|
.product-info .img-wrapper {
|
||||||
height: 150px;
|
height: 150px;
|
||||||
margin: 0.5em 0;
|
margin: 0.5em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#product-info .rogue-item-warning {
|
.product-info .rogue-item-warning {
|
||||||
|
background: #f66;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mispick-dialog input[type="text"],
|
||||||
|
#ordered-product-info {
|
||||||
|
width: 320px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ordered-product-info .warning {
|
||||||
background: #f66;
|
background: #f66;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -124,36 +266,51 @@
|
||||||
<div class="form-wrapper">
|
<div class="form-wrapper">
|
||||||
${form.begin(id='receiving-form')}
|
${form.begin(id='receiving-form')}
|
||||||
${h.hidden('mode')}
|
${h.hidden('mode')}
|
||||||
|
${h.hidden('expiration_date')}
|
||||||
|
${h.hidden('ordered_product')}
|
||||||
|
|
||||||
<div class="field-wrapper">
|
<div class="field-wrapper">
|
||||||
<label for="product-textbox">Product</label>
|
<label for="product-textbox">Product</label>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
${h.hidden('product')}
|
${h.hidden('product')}
|
||||||
<div>${h.text('product-textbox', autocomplete='off')}</div>
|
<div>${h.text('product-textbox', autocomplete='off')}</div>
|
||||||
<div id="product-info">
|
<div id="received-product-info" class="product-info">
|
||||||
<p> </p>
|
<p>please ENTER a scancode</p>
|
||||||
<div class="img-wrapper"><img /></div>
|
<div class="img-wrapper"><img /></div>
|
||||||
<div class="rogue-item-warning">warning: product not found on current purchase</div>
|
<div class="rogue-item-warning">warning: product not found on current purchase</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field-wrapper">
|
<div class="field-wrapper cases">
|
||||||
<label for="cases">Cases</label>
|
<label for="cases">Cases</label>
|
||||||
<div class="field">${h.text('cases')}</div>
|
<div class="field">${h.text('cases', autocomplete='off')}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field-wrapper">
|
<div class="field-wrapper units">
|
||||||
<label for="units">Units</label>
|
<label for="units">Units</label>
|
||||||
<div class="field">${h.text('units')}</div>
|
<div class="field">${h.text('units', autocomplete='off')}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<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" disabled="disabled">Mispick</button>
|
<button type="button" id="mispick">Mispick</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
${form.end()}
|
${form.end()}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="expiration" style="display: none;">
|
||||||
|
${h.text('expiration-date', type='date')}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="mispick-dialog" style="display: none;">
|
||||||
|
<div>${h.text('ordered-product-textbox', autocomplete='off')}</div>
|
||||||
|
<div id="ordered-product-info" class="product-info">
|
||||||
|
<p>please ENTER a scancode</p>
|
||||||
|
<div class="img-wrapper"><img /></div>
|
||||||
|
<div class="warning">warning: product not found on current purchase</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
|
@ -53,13 +53,12 @@ log = logging.getLogger(__name__)
|
||||||
class ReceivingForm(forms.Schema):
|
class ReceivingForm(forms.Schema):
|
||||||
allow_extra_fields = True
|
allow_extra_fields = True
|
||||||
filter_extra_fields = True
|
filter_extra_fields = True
|
||||||
mode = fe.validators.OneOf([
|
mode = fe.validators.OneOf(['received', 'damaged', 'expired', 'mispick'])
|
||||||
'received', 'damaged', 'expired',
|
|
||||||
# 'mispick',
|
|
||||||
])
|
|
||||||
product = forms.validators.ValidProduct()
|
product = forms.validators.ValidProduct()
|
||||||
cases = fe.validators.Int()
|
cases = fe.validators.Int()
|
||||||
units = fe.validators.Int()
|
units = fe.validators.Int()
|
||||||
|
expiration_date = fe.validators.DateValidator()
|
||||||
|
ordered_product = forms.validators.ValidProduct()
|
||||||
|
|
||||||
|
|
||||||
class PurchaseBatchView(BatchMasterView):
|
class PurchaseBatchView(BatchMasterView):
|
||||||
|
@ -307,6 +306,10 @@ class PurchaseBatchView(BatchMasterView):
|
||||||
'tailbone', 'purchases.order_form.vendor_cost_warning_threshold', default=699)
|
'tailbone', 'purchases.order_form.vendor_cost_warning_threshold', default=699)
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
|
def get_row_data(self, batch):
|
||||||
|
query = super(PurchaseBatchView, self).get_row_data(batch)
|
||||||
|
return query.options(orm.joinedload(model.PurchaseBatchRow.credits))
|
||||||
|
|
||||||
def _preconfigure_row_grid(self, g):
|
def _preconfigure_row_grid(self, g):
|
||||||
super(PurchaseBatchView, self)._preconfigure_row_grid(g)
|
super(PurchaseBatchView, self)._preconfigure_row_grid(g)
|
||||||
|
|
||||||
|
@ -321,6 +324,8 @@ class PurchaseBatchView(BatchMasterView):
|
||||||
g.units_received.set(label="Units Rec.")
|
g.units_received.set(label="Units Rec.")
|
||||||
g.po_total.set(label="Total", renderer=forms.renderers.CurrencyFieldRenderer)
|
g.po_total.set(label="Total", renderer=forms.renderers.CurrencyFieldRenderer)
|
||||||
g.invoice_total.set(label="Total", renderer=forms.renderers.CurrencyFieldRenderer)
|
g.invoice_total.set(label="Total", renderer=forms.renderers.CurrencyFieldRenderer)
|
||||||
|
g.append(fa.Field('has_credits', type=fa.types.Boolean, label="Credits?",
|
||||||
|
value=lambda row: bool(row.credits)))
|
||||||
|
|
||||||
def configure_row_grid(self, g):
|
def configure_row_grid(self, g):
|
||||||
batch = self.get_instance()
|
batch = self.get_instance()
|
||||||
|
@ -338,6 +343,7 @@ class PurchaseBatchView(BatchMasterView):
|
||||||
g.units_received,
|
g.units_received,
|
||||||
g.po_total,
|
g.po_total,
|
||||||
g.invoice_total,
|
g.invoice_total,
|
||||||
|
g.has_credits,
|
||||||
g.status_code,
|
g.status_code,
|
||||||
],
|
],
|
||||||
readonly=True)
|
readonly=True)
|
||||||
|
@ -368,6 +374,7 @@ class PurchaseBatchView(BatchMasterView):
|
||||||
fs.po_unit_cost.set(label="PO Unit Cost")
|
fs.po_unit_cost.set(label="PO Unit Cost")
|
||||||
fs.po_total.set(label="PO Total", renderer=forms.renderers.CurrencyFieldRenderer)
|
fs.po_total.set(label="PO Total", renderer=forms.renderers.CurrencyFieldRenderer)
|
||||||
fs.invoice_total.set(renderer=forms.renderers.CurrencyFieldRenderer)
|
fs.invoice_total.set(renderer=forms.renderers.CurrencyFieldRenderer)
|
||||||
|
fs.credits.set(readonly=True)
|
||||||
fs.append(fa.Field('item_lookup', label="Item Lookup Code", required=True,
|
fs.append(fa.Field('item_lookup', label="Item Lookup Code", required=True,
|
||||||
validate=self.item_lookup))
|
validate=self.item_lookup))
|
||||||
|
|
||||||
|
@ -410,9 +417,12 @@ class PurchaseBatchView(BatchMasterView):
|
||||||
fs.units_damaged,
|
fs.units_damaged,
|
||||||
fs.cases_expired,
|
fs.cases_expired,
|
||||||
fs.units_expired,
|
fs.units_expired,
|
||||||
|
fs.cases_mispick,
|
||||||
|
fs.units_mispick,
|
||||||
fs.po_total,
|
fs.po_total,
|
||||||
fs.invoice_total,
|
fs.invoice_total,
|
||||||
fs.status_code,
|
fs.status_code,
|
||||||
|
fs.credits,
|
||||||
])
|
])
|
||||||
|
|
||||||
if self.creating:
|
if self.creating:
|
||||||
|
@ -472,6 +482,8 @@ class PurchaseBatchView(BatchMasterView):
|
||||||
raise httpexceptions.HTTPNotFound()
|
raise httpexceptions.HTTPNotFound()
|
||||||
if row.po_total:
|
if row.po_total:
|
||||||
row.batch.po_total -= row.po_total
|
row.batch.po_total -= row.po_total
|
||||||
|
if row.invoice_total:
|
||||||
|
row.batch.invoice_total -= row.invoice_total
|
||||||
row.removed = True
|
row.removed = True
|
||||||
return self.redirect(self.get_action_url('view', row.batch))
|
return self.redirect(self.get_action_url('view', row.batch))
|
||||||
|
|
||||||
|
@ -623,6 +635,43 @@ 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):
|
||||||
|
batch = row.batch
|
||||||
|
credit = model.PurchaseBatchCredit()
|
||||||
|
credit.credit_type = credit_type
|
||||||
|
credit.store = batch.store
|
||||||
|
credit.vendor = batch.vendor
|
||||||
|
credit.date_ordered = batch.date_ordered
|
||||||
|
credit.date_shipped = batch.date_shipped
|
||||||
|
credit.date_received = batch.date_received
|
||||||
|
credit.invoice_number = batch.invoice_number
|
||||||
|
credit.invoice_date = batch.invoice_date
|
||||||
|
credit.product = row.product
|
||||||
|
credit.upc = row.upc
|
||||||
|
credit.brand_name = row.brand_name
|
||||||
|
credit.description = row.description
|
||||||
|
credit.size = row.size
|
||||||
|
credit.department_number = row.department_number
|
||||||
|
credit.department_name = row.department_name
|
||||||
|
credit.case_quantity = row.case_quantity
|
||||||
|
credit.cases_shorted = cases
|
||||||
|
credit.units_shorted = units
|
||||||
|
credit.invoice_line_number = row.invoice_line_number
|
||||||
|
credit.invoice_case_cost = row.invoice_case_cost
|
||||||
|
credit.invoice_unit_cost = row.invoice_unit_cost
|
||||||
|
credit.invoice_total = row.invoice_total
|
||||||
|
if credit_type == 'expired':
|
||||||
|
credit.expiration_date = expiration_date
|
||||||
|
elif credit_type == 'mispick' and mispick_product:
|
||||||
|
credit.mispick_product = mispick_product
|
||||||
|
credit.mispick_upc = mispick_product.upc
|
||||||
|
if mispick_product.brand:
|
||||||
|
credit.mispick_brand_name = mispick_product.brand.name
|
||||||
|
credit.mispick_description = mispick_product.description
|
||||||
|
credit.mispick_size = mispick_product.size
|
||||||
|
row.credits.append(credit)
|
||||||
|
return credit
|
||||||
|
|
||||||
def receiving_form(self):
|
def receiving_form(self):
|
||||||
"""
|
"""
|
||||||
Workflow view for receiving items on a purchase batch.
|
Workflow view for receiving items on a purchase batch.
|
||||||
|
@ -634,7 +683,9 @@ class PurchaseBatchView(BatchMasterView):
|
||||||
form = forms.SimpleForm(self.request, schema=ReceivingForm)
|
form = forms.SimpleForm(self.request, schema=ReceivingForm)
|
||||||
if form.validate():
|
if form.validate():
|
||||||
|
|
||||||
product = form.data['product']
|
mode = form.data['mode']
|
||||||
|
shipped_product = form.data['product']
|
||||||
|
product = form.data['ordered_product'] if mode == 'mispick' else shipped_product
|
||||||
rows = [row for row in batch.active_rows() if row.product is product]
|
rows = [row for row in batch.active_rows() if row.product is product]
|
||||||
if rows:
|
if rows:
|
||||||
if len(rows) > 1:
|
if len(rows) > 1:
|
||||||
|
@ -644,20 +695,22 @@ class PurchaseBatchView(BatchMasterView):
|
||||||
else:
|
else:
|
||||||
row = model.PurchaseBatchRow()
|
row = model.PurchaseBatchRow()
|
||||||
row.product = product
|
row.product = product
|
||||||
|
|
||||||
mode = form.data['mode']
|
|
||||||
if mode in ('received', 'damaged', 'expired'):
|
|
||||||
if form.data['cases']:
|
|
||||||
setattr(row, 'cases_{}'.format(mode),
|
|
||||||
(getattr(row, 'cases_{}'.format(mode)) or 0) + form.data['cases'])
|
|
||||||
if form.data['units']:
|
|
||||||
setattr(row, 'units_{}'.format(mode),
|
|
||||||
(getattr(row, 'units_{}'.format(mode)) or 0) + form.data['units'])
|
|
||||||
else:
|
|
||||||
assert False # TODO (mispick)
|
|
||||||
|
|
||||||
if not row.uuid:
|
|
||||||
batch.add_row(row)
|
batch.add_row(row)
|
||||||
|
|
||||||
|
cases = form.data['cases']
|
||||||
|
units = form.data['units']
|
||||||
|
if cases:
|
||||||
|
setattr(row, 'cases_{}'.format(mode),
|
||||||
|
(getattr(row, 'cases_{}'.format(mode)) or 0) + cases)
|
||||||
|
if units:
|
||||||
|
setattr(row, 'units_{}'.format(mode),
|
||||||
|
(getattr(row, 'units_{}'.format(mode)) or 0) + units)
|
||||||
|
|
||||||
|
if mode in ('damaged', 'expired', 'mispick'):
|
||||||
|
self.attach_credit(row, mode, cases, units,
|
||||||
|
expiration_date=form.data['expiration_date'],
|
||||||
|
mispick_product=shipped_product)
|
||||||
|
|
||||||
self.handler.refresh_row(row)
|
self.handler.refresh_row(row)
|
||||||
|
|
||||||
self.request.session.flash("({}) {} cases, {} units: {} {}".format(
|
self.request.session.flash("({}) {} cases, {} units: {} {}".format(
|
||||||
|
|
Loading…
Reference in a new issue