Refactor purchasing batch views to use master3
This commit is contained in:
parent
d20601c359
commit
eac59ba5c8
|
@ -54,18 +54,9 @@
|
|||
</ul>
|
||||
|
||||
<div class="form-wrapper">
|
||||
## TODO: clean this up or fix etc..?
|
||||
## % if master.edit_with_rows:
|
||||
## ${form.render(buttons=capture(buttons))|n}
|
||||
## % else:
|
||||
${form.render()|n}
|
||||
## % endif
|
||||
${form.render()|n}
|
||||
</div>
|
||||
|
||||
% if master.edit_with_rows:
|
||||
${rows_grid.render_complete(allow_save_defaults=False, tools=capture(self.grid_tools))|n}
|
||||
% endif
|
||||
|
||||
<div id="execution-options-dialog" style="display: none;">
|
||||
|
||||
${h.form(url('{}.execute'.format(route_prefix), uuid=batch.uuid), name='batch-execution')}
|
||||
|
|
|
@ -51,7 +51,6 @@
|
|||
}
|
||||
});
|
||||
|
||||
// show_mode(${form.fieldset.model.mode or enum.PURCHASE_BATCH_MODE_ORDERING});
|
||||
show_mode(${enum.PURCHASE_BATCH_MODE_ORDERING});
|
||||
|
||||
});
|
||||
|
|
|
@ -65,7 +65,6 @@ class BatchMasterView(MasterView):
|
|||
rows_downloadable_csv = True
|
||||
refreshable = True
|
||||
refresh_after_create = False
|
||||
edit_with_rows = False
|
||||
cloneable = False
|
||||
executable = True
|
||||
results_executable = False
|
||||
|
@ -311,53 +310,14 @@ class BatchMasterView(MasterView):
|
|||
else:
|
||||
return self.redirect(self.get_action_url('view', batch, mobile=mobile))
|
||||
|
||||
# TODO: some of this at least can go to master now right?
|
||||
def edit(self):
|
||||
"""
|
||||
Don't allow editing a batch which has already been executed.
|
||||
"""
|
||||
self.editing = True
|
||||
batch = self.get_instance()
|
||||
if not self.editable_instance(batch):
|
||||
return self.redirect(self.get_action_url('view', batch))
|
||||
|
||||
if self.edit_with_rows:
|
||||
grid = self.make_row_grid(batch=batch)
|
||||
|
||||
# If user just refreshed the page with a reset instruction, issue a
|
||||
# redirect in order to clear out the query string.
|
||||
if self.request.GET.get('reset-to-default-filters') == 'true':
|
||||
return self.redirect(self.request.current_route_url(_query=None))
|
||||
|
||||
if self.request.params.get('partial'):
|
||||
self.request.response.content_type = b'text/html'
|
||||
self.request.response.text = grid.render_grid()
|
||||
return self.request.response
|
||||
|
||||
form = self.make_form(batch)
|
||||
if self.request.method == 'POST':
|
||||
if self.validate_form(form):
|
||||
self.save_edit_form(form)
|
||||
self.request.session.flash("{} has been updated: {}".format(
|
||||
self.get_model_title(), self.get_instance_title(batch)))
|
||||
return self.redirect_after_edit(batch)
|
||||
|
||||
context = {
|
||||
'instance': batch,
|
||||
'instance_title': self.get_instance_title(batch),
|
||||
'instance_deletable': self.deletable_instance(batch),
|
||||
'form': form,
|
||||
'batch': batch,
|
||||
'execute_title': self.get_execute_title(batch),
|
||||
'execute_enabled': self.instance_executable(batch),
|
||||
}
|
||||
|
||||
if self.edit_with_rows:
|
||||
context['rows_grid'] = grid
|
||||
if context['execute_enabled'] and self.has_execution_options(batch):
|
||||
context['rendered_execution_options'] = self.render_execution_options(batch)
|
||||
|
||||
return self.render_to_response('edit', context)
|
||||
def template_kwargs_edit(self, **kwargs):
|
||||
batch = kwargs['instance']
|
||||
kwargs['batch'] = batch
|
||||
kwargs['execute_title'] = self.get_execute_title(batch)
|
||||
kwargs['execute_enabled'] = self.instance_executable(batch)
|
||||
if kwargs['execute_enabled'] and self.has_execution_options(batch):
|
||||
kwargs['rendered_execution_options'] = self.render_execution_options(batch)
|
||||
return kwargs
|
||||
|
||||
def mobile_mark_complete(self):
|
||||
batch = self.get_instance()
|
||||
|
@ -429,8 +389,6 @@ class BatchMasterView(MasterView):
|
|||
"""
|
||||
if self.request.params.get('refresh') == 'true':
|
||||
return self.redirect(self.get_action_url('refresh', batch))
|
||||
if self.edit_with_rows:
|
||||
return self.redirect(self.get_action_url('edit', batch))
|
||||
return self.redirect(self.get_action_url('view', batch))
|
||||
|
||||
def delete_instance(self, batch):
|
||||
|
|
|
@ -76,6 +76,7 @@ class BatchMasterView3(MasterView3, BatchMasterView2):
|
|||
f.set_label('rowcount', "Row Count")
|
||||
|
||||
# status_code
|
||||
f.set_readonly('status_code')
|
||||
f.set_renderer('status_code', self.make_status_renderer(self.model_class.STATUS))
|
||||
f.set_label('status_code', "Status")
|
||||
|
||||
|
@ -141,7 +142,7 @@ class BatchMasterView3(MasterView3, BatchMasterView2):
|
|||
return batch
|
||||
|
||||
def make_status_renderer(self, enum):
|
||||
def render_status(self, batch, field):
|
||||
def render_status(batch, field):
|
||||
value = batch.status_code
|
||||
if value is None:
|
||||
return ""
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2017 Lance Edgar
|
||||
# Copyright © 2010-2018 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -26,17 +26,18 @@ Base views for purchasing batches
|
|||
|
||||
from __future__ import unicode_literals, absolute_import
|
||||
|
||||
# from sqlalchemy import orm
|
||||
import six
|
||||
|
||||
from rattail.db import model, api
|
||||
# from rattail.gpc import GPC
|
||||
from rattail.time import localtime
|
||||
|
||||
import formalchemy as fa
|
||||
import colander
|
||||
from deform import widget as dfwidget
|
||||
from pyramid import httpexceptions
|
||||
from webhelpers2.html import tags
|
||||
|
||||
from tailbone import forms
|
||||
from tailbone.views.batch import BatchMasterView2 as BatchMasterView
|
||||
from tailbone import forms, forms2
|
||||
from tailbone.views.batch import BatchMasterView3 as BatchMasterView
|
||||
|
||||
|
||||
class PurchasingBatchView(BatchMasterView):
|
||||
|
@ -76,6 +77,33 @@ class PurchasingBatchView(BatchMasterView):
|
|||
# 'status_code',
|
||||
# ]
|
||||
|
||||
form_fields = [
|
||||
'id',
|
||||
'store',
|
||||
'buyer',
|
||||
'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',
|
||||
]
|
||||
|
||||
@property
|
||||
def batch_mode(self):
|
||||
raise NotImplementedError("Please define `batch_mode` for your purchasing batch view")
|
||||
|
@ -118,29 +146,189 @@ class PurchasingBatchView(BatchMasterView):
|
|||
# form = super(PurchasingBatchView, self).make_form(batch, **kwargs)
|
||||
# return form
|
||||
|
||||
def _preconfigure_fieldset(self, fs):
|
||||
super(PurchasingBatchView, self)._preconfigure_fieldset(fs)
|
||||
fs.mode.set(renderer=forms.renderers.EnumFieldRenderer(self.enum.PURCHASE_BATCH_MODE))
|
||||
fs.store.set(renderer=forms.renderers.StoreFieldRenderer)
|
||||
fs.purchase.set(renderer=forms.renderers.PurchaseFieldRenderer, options=[])
|
||||
fs.vendor.set(renderer=forms.renderers.VendorFieldRenderer,
|
||||
attrs={'selected': 'vendor_selected',
|
||||
'cleared': 'vendor_cleared'})
|
||||
fs.department.set(renderer=forms.renderers.DepartmentFieldRenderer,
|
||||
options=self.get_department_options())
|
||||
fs.buyer.set(renderer=forms.renderers.EmployeeFieldRenderer)
|
||||
fs.po_number.set(label="PO Number")
|
||||
fs.po_total.set(label="PO Total", readonly=True, renderer=forms.renderers.CurrencyFieldRenderer)
|
||||
fs.invoice_total.set(readonly=True, renderer=forms.renderers.CurrencyFieldRenderer)
|
||||
def configure_form(self, f):
|
||||
super(PurchasingBatchView, self).configure_form(f)
|
||||
batch = f.model_instance
|
||||
today = localtime(self.rattail_config).date()
|
||||
|
||||
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))
|
||||
# mode
|
||||
f.set_enum('mode', self.enum.PURCHASE_BATCH_MODE)
|
||||
|
||||
# TODO: this hardly seems complete...
|
||||
# store
|
||||
if not self.creating:
|
||||
f.set_readonly('store')
|
||||
f.set_renderer('store', self.render_store)
|
||||
|
||||
# purchase
|
||||
f.set_renderer('purchase', self.render_purchase)
|
||||
if self.editing:
|
||||
f.set_readonly('purchase')
|
||||
|
||||
# vendor
|
||||
# fs.vendor.set(renderer=forms.renderers.VendorFieldRenderer,
|
||||
# attrs={'selected': 'vendor_selected',
|
||||
# 'cleared': 'vendor_cleared'})
|
||||
f.set_renderer('vendor', self.render_vendor)
|
||||
if self.creating:
|
||||
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', forms2.widgets.JQueryAutocompleteWidget(
|
||||
field_display=vendor_display, service_url=vendors_url))
|
||||
f.set_label('vendor_uuid', "Vendor")
|
||||
elif self.editing:
|
||||
f.set_readonly('vendor')
|
||||
|
||||
# department
|
||||
f.set_renderer('department', self.render_department)
|
||||
if self.creating:
|
||||
f.replace('department', 'department_uuid')
|
||||
f.set_node('department_uuid', colander.String())
|
||||
dept_options = self.get_department_options()
|
||||
dept_values = [(v, k) for k, v in dept_options]
|
||||
f.set_widget('department_uuid', dfwidget.SelectWidget(values=dept_values))
|
||||
f.set_label('department_uuid', "Department")
|
||||
else:
|
||||
f.set_readonly('department')
|
||||
|
||||
# buyer
|
||||
f.set_renderer('buyer', self.render_buyer)
|
||||
if self.creating or self.editing:
|
||||
f.replace('buyer', 'buyer_uuid')
|
||||
f.set_node('buyer_uuid', colander.String(), missing=colander.null)
|
||||
buyer_display = ""
|
||||
if self.request.method == 'POST':
|
||||
if self.request.POST.get('buyer_uuid'):
|
||||
buyer = self.Session.query(model.Employee).get(self.request.POST['buyer_uuid'])
|
||||
if buyer:
|
||||
buyer_display = six.text_type(buyer)
|
||||
elif self.creating:
|
||||
buyer = self.request.user.employee
|
||||
buyer_display = six.text_type(buyer)
|
||||
f.set_default('buyer_uuid', buyer.uuid)
|
||||
elif self.editing:
|
||||
buyer_display = six.text_type(batch.buyer or '')
|
||||
buyers_url = self.request.route_url('employees.autocomplete')
|
||||
f.set_widget('buyer_uuid', forms2.widgets.JQueryAutocompleteWidget(
|
||||
field_display=buyer_display, service_url=buyers_url))
|
||||
f.set_label('buyer_uuid', "Buyer")
|
||||
|
||||
# date_ordered
|
||||
f.set_type('date_ordered', 'date_jquery')
|
||||
if self.creating:
|
||||
f.set_default('date_ordered', today)
|
||||
|
||||
# date_received
|
||||
f.set_type('date_received', 'date_jquery')
|
||||
if self.creating:
|
||||
f.set_default('date_received', today)
|
||||
|
||||
# invoice_date
|
||||
f.set_type('invoice_date', 'date_jquery')
|
||||
|
||||
# po_number
|
||||
f.set_label('po_number', "PO Number")
|
||||
|
||||
# po_total
|
||||
f.set_readonly('po_total')
|
||||
f.set_type('po_total', 'currency')
|
||||
f.set_label('po_total', "PO Total")
|
||||
|
||||
# invoice_total
|
||||
f.set_readonly('invoice_total')
|
||||
f.set_type('invoice_total', 'currency')
|
||||
|
||||
# vendor_email
|
||||
f.set_readonly('vendor_email')
|
||||
f.set_renderer('vendor_email', self.render_vendor_email)
|
||||
|
||||
# vendor_fax
|
||||
f.set_readonly('vendor_fax')
|
||||
f.set_renderer('vendor_fax', self.render_vendor_fax)
|
||||
|
||||
# vendor_contact
|
||||
f.set_readonly('vendor_contact')
|
||||
f.set_renderer('vendor_contact', self.render_vendor_contact)
|
||||
|
||||
# vendor_phone
|
||||
f.set_readonly('vendor_phone')
|
||||
f.set_renderer('vendor_phone', self.render_vendor_phone)
|
||||
|
||||
if self.creating:
|
||||
f.remove_fields('po_total',
|
||||
'invoice_total',
|
||||
'complete',
|
||||
'vendor_email',
|
||||
'vendor_fax',
|
||||
'vendor_phone',
|
||||
'vendor_contact',
|
||||
'status_code')
|
||||
|
||||
def render_store(self, batch, field):
|
||||
store = batch.store
|
||||
if not store:
|
||||
return ""
|
||||
text = "({}) {}".format(store.id, store.name)
|
||||
url = self.request.route_url('stores.view', uuid=store.uuid)
|
||||
return tags.link_to(text, url)
|
||||
|
||||
def render_purchase(self, batch, field):
|
||||
purchase = batch.purchase
|
||||
if not purchase:
|
||||
return ""
|
||||
text = six.text_type(purchase)
|
||||
url = self.request.route_url('purchases.view', uuid=purchase.uuid)
|
||||
return tags.link_to(text, url)
|
||||
|
||||
def render_vendor(self, batch, field):
|
||||
vendor = batch.vendor
|
||||
if not vendor:
|
||||
return ""
|
||||
text = "({}) {}".format(vendor.id, vendor.name)
|
||||
url = self.request.route_url('vendors.view', uuid=vendor.uuid)
|
||||
return tags.link_to(text, url)
|
||||
|
||||
def render_vendor_email(self, batch, field):
|
||||
if batch.vendor.email:
|
||||
return batch.vendor.email.address
|
||||
|
||||
def render_vendor_fax(self, batch, field):
|
||||
return self.get_vendor_fax_number(batch)
|
||||
|
||||
def render_vendor_contact(self, batch, field):
|
||||
if batch.vendor.contact:
|
||||
return six.text_type(batch.vendor.contact)
|
||||
|
||||
def render_vendor_phone(self, batch, field):
|
||||
return self.get_vendor_phone_number(batch)
|
||||
|
||||
def render_department(self, batch, field):
|
||||
department = batch.department
|
||||
if not department:
|
||||
return ""
|
||||
if department.number:
|
||||
text = "({}) {}".format(department.number, department.name)
|
||||
else:
|
||||
text = department.name
|
||||
url = self.request.route_url('departments.view', uuid=department.uuid)
|
||||
return tags.link_to(text, url)
|
||||
|
||||
def render_buyer(self, batch, field):
|
||||
employee = batch.buyer
|
||||
if not employee:
|
||||
return ""
|
||||
text = six.text_type(employee)
|
||||
if self.request.has_perm('employees.view'):
|
||||
url = self.request.route_url('employees.view', uuid=employee.uuid)
|
||||
return tags.link_to(text, url)
|
||||
return text
|
||||
|
||||
def get_department_options(self):
|
||||
departments = self.Session.query(model.Department).order_by(model.Department.number)
|
||||
|
@ -156,70 +344,6 @@ class PurchasingBatchView(BatchMasterView):
|
|||
if phone.type == 'Fax':
|
||||
return phone.number
|
||||
|
||||
def configure_fieldset(self, fs):
|
||||
fs.configure(
|
||||
include=[
|
||||
fs.id,
|
||||
fs.store,
|
||||
fs.buyer,
|
||||
fs.vendor,
|
||||
fs.department,
|
||||
fs.purchase,
|
||||
fs.vendor_email,
|
||||
fs.vendor_fax,
|
||||
fs.vendor_contact,
|
||||
fs.vendor_phone,
|
||||
fs.date_ordered,
|
||||
fs.date_received,
|
||||
fs.po_number,
|
||||
fs.po_total,
|
||||
fs.invoice_date,
|
||||
fs.invoice_number,
|
||||
fs.invoice_total,
|
||||
fs.notes,
|
||||
fs.created,
|
||||
fs.created_by,
|
||||
fs.status_code,
|
||||
fs.complete,
|
||||
fs.executed,
|
||||
fs.executed_by,
|
||||
])
|
||||
|
||||
if self.creating:
|
||||
del fs.po_total
|
||||
del fs.invoice_total
|
||||
del fs.complete
|
||||
del fs.vendor_email
|
||||
del fs.vendor_fax
|
||||
del fs.vendor_phone
|
||||
del fs.vendor_contact
|
||||
del fs.status_code
|
||||
|
||||
# default store may be configured
|
||||
store = self.rattail_config.get('rattail', 'store')
|
||||
if store:
|
||||
store = api.get_store(self.Session(), store)
|
||||
if store:
|
||||
fs.model.store = store
|
||||
|
||||
# default buyer is current user
|
||||
if self.request.method != 'POST':
|
||||
buyer = self.request.user.employee
|
||||
if buyer:
|
||||
fs.model.buyer = buyer
|
||||
|
||||
# TODO: something tells me this isn't quite safe..
|
||||
# all dates have today as default
|
||||
today = localtime(self.rattail_config).date()
|
||||
fs.model.date_ordered = today
|
||||
fs.model.date_received = today
|
||||
|
||||
elif self.editing:
|
||||
fs.store.set(readonly=True)
|
||||
fs.vendor.set(readonly=True)
|
||||
fs.department.set(readonly=True)
|
||||
fs.purchase.set(readonly=True)
|
||||
|
||||
def eligible_purchases(self, vendor_uuid=None, mode=None):
|
||||
if not vendor_uuid:
|
||||
vendor_uuid = self.request.GET.get('vendor_uuid')
|
||||
|
|
|
@ -86,6 +86,12 @@ class OrderingBatchView(PurchasingBatchView):
|
|||
def batch_mode(self):
|
||||
return self.enum.PURCHASE_BATCH_MODE_ORDERING
|
||||
|
||||
def configure_form(self, f):
|
||||
super(OrderingBatchView, self).configure_form(f)
|
||||
|
||||
# purchase
|
||||
f.remove_field('purchase')
|
||||
|
||||
def order_form(self):
|
||||
"""
|
||||
View for editing batch row data as an order form.
|
||||
|
|
Loading…
Reference in a new issue