Improve default behavior for receiving a purchase batch
only targeting desktop so far, mobile is next...
This commit is contained in:
parent
e6144ea08b
commit
a5d1eece71
|
@ -310,6 +310,17 @@ class PurchaseView(MasterView):
|
||||||
# department
|
# department
|
||||||
f.set_renderer('department', self.render_row_department)
|
f.set_renderer('department', self.render_row_department)
|
||||||
|
|
||||||
|
# product
|
||||||
|
f.set_renderer('product', self.render_row_product)
|
||||||
|
|
||||||
|
def render_row_product(self, row, field):
|
||||||
|
product = row.product
|
||||||
|
if not product:
|
||||||
|
return ""
|
||||||
|
text = six.text_type(product)
|
||||||
|
url = self.request.route_url('products.view', uuid=product.uuid)
|
||||||
|
return tags.link_to(text, url)
|
||||||
|
|
||||||
def render_row_department(self, row, field):
|
def render_row_department(self, row, field):
|
||||||
return "{} {}".format(row.department_number, row.department_name)
|
return "{} {}".format(row.department_number, row.department_name)
|
||||||
|
|
||||||
|
|
|
@ -221,15 +221,24 @@ class PurchasingBatchView(BatchMasterView):
|
||||||
# mode
|
# mode
|
||||||
f.set_enum('mode', self.enum.PURCHASE_BATCH_MODE)
|
f.set_enum('mode', self.enum.PURCHASE_BATCH_MODE)
|
||||||
|
|
||||||
# TODO: this hardly seems complete...
|
|
||||||
# store
|
# store
|
||||||
|
single_store = self.rattail_config.single_store()
|
||||||
if self.creating:
|
if self.creating:
|
||||||
f.replace('store', 'store_uuid')
|
f.replace('store', 'store_uuid')
|
||||||
f.set_widget('store_uuid', dfwidget.SelectWidget(values=self.get_store_values()))
|
if single_store:
|
||||||
f.set_label('store_uuid', "Store")
|
store = self.rattail_config.get_store(self.Session())
|
||||||
|
f.set_widget('store_uuid', forms.widgets.ReadonlyWidget())
|
||||||
|
f.set_default('store_uuid', store.uuid)
|
||||||
|
f.set_hidden('store_uuid')
|
||||||
|
else:
|
||||||
|
f.set_widget('store_uuid', dfwidget.SelectWidget(values=self.get_store_values()))
|
||||||
|
f.set_label('store_uuid', "Store")
|
||||||
else:
|
else:
|
||||||
f.set_readonly('store')
|
if single_store:
|
||||||
f.set_renderer('store', self.render_store)
|
f.remove_field('store')
|
||||||
|
else:
|
||||||
|
f.set_readonly('store')
|
||||||
|
f.set_renderer('store', self.render_store)
|
||||||
|
|
||||||
# purchase
|
# purchase
|
||||||
f.set_renderer('purchase', self.render_purchase)
|
f.set_renderer('purchase', self.render_purchase)
|
||||||
|
@ -243,17 +252,27 @@ class PurchasingBatchView(BatchMasterView):
|
||||||
f.set_renderer('vendor', self.render_vendor)
|
f.set_renderer('vendor', self.render_vendor)
|
||||||
if self.creating:
|
if self.creating:
|
||||||
f.replace('vendor', 'vendor_uuid')
|
f.replace('vendor', 'vendor_uuid')
|
||||||
f.set_node('vendor_uuid', colander.String())
|
|
||||||
vendor_display = ""
|
|
||||||
if self.request.method == 'POST':
|
|
||||||
if self.request.POST.get('vendor_uuid'):
|
|
||||||
vendor = self.Session.query(model.Vendor).get(self.request.POST['vendor_uuid'])
|
|
||||||
if vendor:
|
|
||||||
vendor_display = six.text_type(vendor)
|
|
||||||
vendors_url = self.request.route_url('vendors.autocomplete')
|
|
||||||
f.set_widget('vendor_uuid', forms.widgets.JQueryAutocompleteWidget(
|
|
||||||
field_display=vendor_display, service_url=vendors_url))
|
|
||||||
f.set_label('vendor_uuid', "Vendor")
|
f.set_label('vendor_uuid', "Vendor")
|
||||||
|
widget_type = self.rattail_config.get('tailbone', 'default_widget.vendor',
|
||||||
|
default='autocomplete')
|
||||||
|
if widget_type == 'autocomplete':
|
||||||
|
vendor_display = ""
|
||||||
|
if self.request.method == 'POST':
|
||||||
|
if self.request.POST.get('vendor_uuid'):
|
||||||
|
vendor = self.Session.query(model.Vendor).get(self.request.POST['vendor_uuid'])
|
||||||
|
if vendor:
|
||||||
|
vendor_display = six.text_type(vendor)
|
||||||
|
vendors_url = self.request.route_url('vendors.autocomplete')
|
||||||
|
f.set_widget('vendor_uuid', forms.widgets.JQueryAutocompleteWidget(
|
||||||
|
field_display=vendor_display, service_url=vendors_url))
|
||||||
|
elif widget_type == 'dropdown':
|
||||||
|
vendors = self.Session.query(model.Vendor)\
|
||||||
|
.order_by(model.Vendor.id)
|
||||||
|
vendor_values = [(vendor.uuid, "({}) {}".format(vendor.id, vendor.name))
|
||||||
|
for vendor in vendors]
|
||||||
|
f.set_widget('vendor_uuid', dfwidget.SelectWidget(values=vendor_values))
|
||||||
|
else:
|
||||||
|
raise NotImplementedError("Unsupported vendor widget type: {}".format(widget_type))
|
||||||
elif self.editing:
|
elif self.editing:
|
||||||
f.set_readonly('vendor')
|
f.set_readonly('vendor')
|
||||||
|
|
||||||
|
@ -271,26 +290,27 @@ class PurchasingBatchView(BatchMasterView):
|
||||||
f.set_readonly('department')
|
f.set_readonly('department')
|
||||||
|
|
||||||
# buyer
|
# buyer
|
||||||
f.set_renderer('buyer', self.render_buyer)
|
if 'buyer' in f:
|
||||||
if self.creating or self.editing:
|
f.set_renderer('buyer', self.render_buyer)
|
||||||
f.replace('buyer', 'buyer_uuid')
|
if self.creating or self.editing:
|
||||||
f.set_node('buyer_uuid', colander.String(), missing=colander.null)
|
f.replace('buyer', 'buyer_uuid')
|
||||||
buyer_display = ""
|
f.set_node('buyer_uuid', colander.String(), missing=colander.null)
|
||||||
if self.request.method == 'POST':
|
buyer_display = ""
|
||||||
if self.request.POST.get('buyer_uuid'):
|
if self.request.method == 'POST':
|
||||||
buyer = self.Session.query(model.Employee).get(self.request.POST['buyer_uuid'])
|
if self.request.POST.get('buyer_uuid'):
|
||||||
if buyer:
|
buyer = self.Session.query(model.Employee).get(self.request.POST['buyer_uuid'])
|
||||||
buyer_display = six.text_type(buyer)
|
if buyer:
|
||||||
elif self.creating:
|
buyer_display = six.text_type(buyer)
|
||||||
buyer = self.request.user.employee
|
elif self.creating:
|
||||||
buyer_display = six.text_type(buyer)
|
buyer = self.request.user.employee
|
||||||
f.set_default('buyer_uuid', buyer.uuid)
|
buyer_display = six.text_type(buyer)
|
||||||
elif self.editing:
|
f.set_default('buyer_uuid', buyer.uuid)
|
||||||
buyer_display = six.text_type(batch.buyer or '')
|
elif self.editing:
|
||||||
buyers_url = self.request.route_url('employees.autocomplete')
|
buyer_display = six.text_type(batch.buyer or '')
|
||||||
f.set_widget('buyer_uuid', forms.widgets.JQueryAutocompleteWidget(
|
buyers_url = self.request.route_url('employees.autocomplete')
|
||||||
field_display=buyer_display, service_url=buyers_url))
|
f.set_widget('buyer_uuid', forms.widgets.JQueryAutocompleteWidget(
|
||||||
f.set_label('buyer_uuid', "Buyer")
|
field_display=buyer_display, service_url=buyers_url))
|
||||||
|
f.set_label('buyer_uuid', "Buyer")
|
||||||
|
|
||||||
# date_ordered
|
# date_ordered
|
||||||
f.set_type('date_ordered', 'date_jquery')
|
f.set_type('date_ordered', 'date_jquery')
|
||||||
|
@ -629,19 +649,33 @@ class PurchasingBatchView(BatchMasterView):
|
||||||
|
|
||||||
elif self.editing:
|
elif self.editing:
|
||||||
f.set_readonly('upc')
|
f.set_readonly('upc')
|
||||||
|
f.set_readonly('item_id')
|
||||||
f.set_readonly('product')
|
f.set_readonly('product')
|
||||||
f.remove_fields('po_total',
|
f.set_renderer('product', self.render_product)
|
||||||
'invoice_total',
|
|
||||||
'status_code')
|
# TODO: what's up with this again?
|
||||||
|
# f.remove_fields('po_total',
|
||||||
|
# 'invoice_total',
|
||||||
|
# 'status_code')
|
||||||
|
|
||||||
elif self.viewing:
|
elif self.viewing:
|
||||||
if row.product:
|
if row.product:
|
||||||
f.remove_fields('brand_name',
|
f.remove_fields('brand_name',
|
||||||
'description',
|
'description',
|
||||||
'size')
|
'size')
|
||||||
|
f.set_renderer('product', self.render_row_product)
|
||||||
else:
|
else:
|
||||||
f.remove_field('product')
|
f.remove_field('product')
|
||||||
|
|
||||||
|
|
||||||
|
def render_row_product(self, row, field):
|
||||||
|
product = row.product
|
||||||
|
if not product:
|
||||||
|
return ""
|
||||||
|
text = six.text_type(product)
|
||||||
|
url = self.request.route_url('products.view', uuid=product.uuid)
|
||||||
|
return tags.link_to(text, url)
|
||||||
|
|
||||||
def configure_mobile_row_form(self, f):
|
def configure_mobile_row_form(self, f):
|
||||||
super(PurchasingBatchView, self).configure_mobile_row_form(f)
|
super(PurchasingBatchView, self).configure_mobile_row_form(f)
|
||||||
# row = f.model_instance
|
# row = f.model_instance
|
||||||
|
@ -786,6 +820,11 @@ class PurchasingBatchView(BatchMasterView):
|
||||||
# self.request.session.flash("Added item: {} {}".format(row.upc.pretty(), row.product))
|
# self.request.session.flash("Added item: {} {}".format(row.upc.pretty(), row.product))
|
||||||
# return self.redirect(self.request.current_route_url())
|
# return self.redirect(self.request.current_route_url())
|
||||||
|
|
||||||
|
# TODO: seems like this should be master behavior, controlled by setting?
|
||||||
|
def redirect_after_edit_row(self, row, mobile=False):
|
||||||
|
parent = self.get_parent(row)
|
||||||
|
return self.redirect(self.get_action_url('view', parent, mobile=mobile))
|
||||||
|
|
||||||
def delete_row(self):
|
def delete_row(self):
|
||||||
"""
|
"""
|
||||||
Update the batch totals in addition to marking row as removed.
|
Update the batch totals in addition to marking row as removed.
|
||||||
|
|
|
@ -89,11 +89,38 @@ class ReceivingBatchView(PurchasingBatchView):
|
||||||
model_title_plural = "Receiving Batches"
|
model_title_plural = "Receiving Batches"
|
||||||
index_title = "Receiving"
|
index_title = "Receiving"
|
||||||
creatable = False
|
creatable = False
|
||||||
|
rows_editable = True
|
||||||
rows_deletable = False
|
rows_deletable = False
|
||||||
mobile_creatable = True
|
mobile_creatable = True
|
||||||
mobile_rows_filterable = True
|
mobile_rows_filterable = True
|
||||||
mobile_rows_creatable = True
|
mobile_rows_creatable = True
|
||||||
|
|
||||||
|
form_fields = [
|
||||||
|
'id',
|
||||||
|
'store',
|
||||||
|
'vendor',
|
||||||
|
'department',
|
||||||
|
'purchase',
|
||||||
|
'vendor_email',
|
||||||
|
'vendor_fax',
|
||||||
|
'vendor_contact',
|
||||||
|
'vendor_phone',
|
||||||
|
'date_ordered',
|
||||||
|
'date_received',
|
||||||
|
'po_number',
|
||||||
|
'po_total',
|
||||||
|
'invoice_date',
|
||||||
|
'invoice_number',
|
||||||
|
'invoice_total',
|
||||||
|
'notes',
|
||||||
|
'created',
|
||||||
|
'created_by',
|
||||||
|
'status_code',
|
||||||
|
'complete',
|
||||||
|
'executed',
|
||||||
|
'executed_by',
|
||||||
|
]
|
||||||
|
|
||||||
mobile_form_fields = [
|
mobile_form_fields = [
|
||||||
'vendor',
|
'vendor',
|
||||||
'department',
|
'department',
|
||||||
|
@ -116,6 +143,34 @@ class ReceivingBatchView(PurchasingBatchView):
|
||||||
'status_code',
|
'status_code',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
row_form_fields = [
|
||||||
|
'upc',
|
||||||
|
'item_id',
|
||||||
|
'product',
|
||||||
|
'brand_name',
|
||||||
|
'description',
|
||||||
|
'size',
|
||||||
|
'case_quantity',
|
||||||
|
'cases_ordered',
|
||||||
|
'units_ordered',
|
||||||
|
'cases_received',
|
||||||
|
'units_received',
|
||||||
|
'cases_damaged',
|
||||||
|
'units_damaged',
|
||||||
|
'cases_expired',
|
||||||
|
'units_expired',
|
||||||
|
'cases_mispick',
|
||||||
|
'units_mispick',
|
||||||
|
'po_line_number',
|
||||||
|
'po_unit_cost',
|
||||||
|
'po_total',
|
||||||
|
'invoice_line_number',
|
||||||
|
'invoice_unit_cost',
|
||||||
|
'invoice_total',
|
||||||
|
'status_code',
|
||||||
|
'credits',
|
||||||
|
]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def batch_mode(self):
|
def batch_mode(self):
|
||||||
return self.enum.PURCHASE_BATCH_MODE_RECEIVING
|
return self.enum.PURCHASE_BATCH_MODE_RECEIVING
|
||||||
|
@ -177,8 +232,6 @@ class ReceivingBatchView(PurchasingBatchView):
|
||||||
if mobile:
|
if mobile:
|
||||||
|
|
||||||
purchase = self.get_purchase(self.request.POST['purchase'])
|
purchase = self.get_purchase(self.request.POST['purchase'])
|
||||||
kwargs['sms_transaction_number'] = purchase.F1032
|
|
||||||
|
|
||||||
numbers = [d.F03 for d in purchase.details]
|
numbers = [d.F03 for d in purchase.details]
|
||||||
if numbers:
|
if numbers:
|
||||||
number = max(set(numbers), key=numbers.count)
|
number = max(set(numbers), key=numbers.count)
|
||||||
|
@ -186,8 +239,6 @@ class ReceivingBatchView(PurchasingBatchView):
|
||||||
.filter(model.Department.number == number)\
|
.filter(model.Department.number == number)\
|
||||||
.one()
|
.one()
|
||||||
|
|
||||||
else:
|
|
||||||
kwargs['sms_transaction_number'] = batch.sms_transaction_number
|
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
def configure_mobile_form(self, f):
|
def configure_mobile_form(self, f):
|
||||||
|
@ -199,6 +250,14 @@ class ReceivingBatchView(PurchasingBatchView):
|
||||||
# department
|
# department
|
||||||
# fs.department.with_renderer(fa.TextFieldRenderer),
|
# fs.department.with_renderer(fa.TextFieldRenderer),
|
||||||
|
|
||||||
|
def configure_row_form(self, f):
|
||||||
|
super(ReceivingBatchView, self).configure_row_form(f)
|
||||||
|
f.set_readonly('cases_ordered')
|
||||||
|
f.set_readonly('units_ordered')
|
||||||
|
f.set_readonly('po_unit_cost')
|
||||||
|
f.set_readonly('po_total')
|
||||||
|
f.set_readonly('invoice_total')
|
||||||
|
|
||||||
def render_mobile_row_listitem(self, row, i):
|
def render_mobile_row_listitem(self, row, i):
|
||||||
description = row.product.full_description if row.product else row.description
|
description = row.product.full_description if row.product else row.description
|
||||||
return "({}) {}".format(row.upc.pretty(), description)
|
return "({}) {}".format(row.upc.pretty(), description)
|
||||||
|
|
Loading…
Reference in a new issue