Add support for 'department' field in purchases / batches

Also fix logic for deleting a purchase (delete its batches first)
This commit is contained in:
Lance Edgar 2016-12-09 14:01:06 -06:00
parent 6c3d221e98
commit c73ba56505
6 changed files with 62 additions and 13 deletions

View file

@ -526,7 +526,12 @@ class MasterView(View):
Return a "humanized" (and plural) version of the model name, for
display in templates.
"""
return getattr(cls, 'model_title_plural', '{0}s'.format(cls.get_model_title()))
if hasattr(cls, 'model_title_plural'):
return cls.model_title_plural
try:
return cls.get_model_class().get_model_title_plural()
except (NotImplementedError, AttributeError):
return '{}s'.format(cls.get_model_title())
@classmethod
def get_route_prefix(cls):

View file

@ -31,7 +31,7 @@ import logging
from sqlalchemy import orm
from rattail import enum, pod
from rattail import pod
from rattail.db import model, api
from rattail.gpc import GPC
from rattail.time import localtime
@ -67,7 +67,6 @@ class PurchaseBatchView(BatchMasterView):
Master view for purchase order batches.
"""
model_class = model.PurchaseBatch
model_title_plural = "Purchase Batches"
model_row_class = model.PurchaseBatchRow
default_handler_spec = 'rattail.batch.purchase:PurchaseBatchHandler'
route_prefix = 'purchases.batch'
@ -87,6 +86,10 @@ class PurchaseBatchView(BatchMasterView):
default_active=True, default_verb='contains')
g.sorters['vendor'] = g.make_sorter(model.Vendor.name)
g.joiners['department'] = lambda q: q.join(model.Department)
g.filters['department'] = g.make_filter('department', model.Department.name)
g.sorters['department'] = g.make_sorter(model.Department.name)
g.joiners['buyer'] = lambda q: q.join(model.Employee).join(model.Person)
g.filters['buyer'] = g.make_filter('buyer', model.Person.display_name,
default_active=True, default_verb='contains')
@ -106,6 +109,7 @@ class PurchaseBatchView(BatchMasterView):
g.id,
g.mode,
g.vendor,
g.department,
g.buyer,
g.date_ordered,
g.created,
@ -121,6 +125,8 @@ class PurchaseBatchView(BatchMasterView):
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)
@ -135,6 +141,10 @@ class PurchaseBatchView(BatchMasterView):
fs.append(fa.Field('vendor_phone', readonly=True,
value=self.get_vendor_phone_number))
def get_department_options(self):
departments = Session.query(model.Department).order_by(model.Department.number)
return [('{} {}'.format(d.number, d.name), d.uuid) for d in departments]
def get_vendor_phone_number(self, batch):
for phone in batch.vendor.phones:
if phone.type == 'Voice':
@ -152,6 +162,7 @@ class PurchaseBatchView(BatchMasterView):
fs.mode,
fs.store,
fs.vendor,
fs.department,
fs.purchase,
fs.vendor_email,
fs.vendor_fax,
@ -208,6 +219,7 @@ class PurchaseBatchView(BatchMasterView):
fs.mode.set(readonly=True)
fs.store.set(readonly=True)
fs.vendor.set(readonly=True)
fs.department.set(readonly=True)
fs.purchase.set(readonly=True)
def eligible_purchases(self):
@ -223,10 +235,10 @@ class PurchaseBatchView(BatchMasterView):
purchases = Session.query(model.Purchase)\
.filter(model.Purchase.vendor == vendor)
if mode == enum.PURCHASE_BATCH_MODE_RECEIVING:
if mode == self.enum.PURCHASE_BATCH_MODE_RECEIVING:
purchases = purchases.filter(model.Purchase.status == self.enum.PURCHASE_STATUS_ORDERED)\
.order_by(model.Purchase.date_ordered, model.Purchase.created)
elif mode == enum.PURCHASE_BATCH_MODE_COSTING:
elif mode == self.enum.PURCHASE_BATCH_MODE_COSTING:
purchases = purchases.filter(model.Purchase.status == self.enum.PURCHASE_STATUS_RECEIVED)\
.order_by(model.Purchase.date_received, model.Purchase.created)
@ -240,7 +252,7 @@ class PurchaseBatchView(BatchMasterView):
elif purchase.status == self.enum.PURCHASE_STATUS_RECEIVED:
date = purchase.date_received
total = purchase.invoice_total
return '{} for ${:0,.2f} ({})'.format(date, total, purchase.buyer)
return '{} for ${:0,.2f} ({})'.format(date, total, purchase.department or purchase.buyer)
def get_batch_kwargs(self, batch):
kwargs = super(PurchaseBatchView, self).get_batch_kwargs(batch)
@ -253,6 +265,10 @@ class PurchaseBatchView(BatchMasterView):
kwargs['vendor'] = batch.vendor
elif batch.vendor_uuid:
kwargs['vendor_uuid'] = batch.vendor_uuid
if batch.department:
kwargs['department'] = batch.department
elif batch.department_uuid:
kwargs['department_uuid'] = batch.department_uuid
if batch.buyer:
kwargs['buyer'] = batch.buyer
elif batch.buyer_uuid:
@ -274,6 +290,8 @@ class PurchaseBatchView(BatchMasterView):
purchase = Session.query(model.Purchase).get(batch.purchase_uuid)
assert purchase
kwargs['purchase'] = purchase
kwargs['buyer'] = purchase.buyer
kwargs['buyer_uuid'] = purchase.buyer_uuid
kwargs['date_ordered'] = purchase.date_ordered
kwargs['po_total'] = purchase.po_total
@ -510,7 +528,7 @@ class PurchaseBatchView(BatchMasterView):
history = OrderedDict()
purchases = Session.query(model.Purchase)\
.filter(model.Purchase.vendor == batch.vendor)\
.filter(model.Purchase.status >= enum.PURCHASE_STATUS_ORDERED)\
.filter(model.Purchase.status >= self.enum.PURCHASE_STATUS_ORDERED)\
.order_by(model.Purchase.date_ordered.desc(), model.Purchase.created.desc())\
.options(orm.joinedload(model.Purchase.items))[:6]
for purchase in purchases[:6]:

View file

@ -100,6 +100,10 @@ class PurchaseView(MasterView):
default_active=True, default_verb='contains')
g.sorters['vendor'] = g.make_sorter(model.Vendor.name)
g.joiners['department'] = lambda q: q.join(model.Department)
g.filters['department'] = g.make_filter('department', model.Department.name)
g.sorters['department'] = g.make_sorter(model.Department.name)
g.joiners['buyer'] = lambda q: q.join(model.Employee).join(model.Person)
g.filters['buyer'] = g.make_filter('buyer', model.Person.display_name,
default_active=True, default_verb='contains')
@ -121,6 +125,7 @@ class PurchaseView(MasterView):
include=[
g.store,
g.vendor,
g.department,
g.buyer,
g.date_ordered,
g.date_received,
@ -130,6 +135,7 @@ class PurchaseView(MasterView):
def _preconfigure_fieldset(self, fs):
fs.vendor.set(renderer=forms.renderers.VendorFieldRenderer)
fs.department.set(renderer=forms.renderers.DepartmentFieldRenderer)
fs.status.set(renderer=forms.renderers.EnumFieldRenderer(self.enum.PURCHASE_STATUS),
readonly=True)
fs.po_number.set(label="PO Number")
@ -142,6 +148,7 @@ class PurchaseView(MasterView):
include=[
fs.store,
fs.vendor,
fs.department,
fs.status,
fs.buyer,
fs.date_ordered,
@ -162,6 +169,16 @@ class PurchaseView(MasterView):
del fs.invoice_number
del fs.invoice_total
def delete_instance(self, purchase):
"""
Delete all batches for the purchase, then delete the purchase.
"""
for batch in list(purchase.batches):
self.Session.delete(batch)
self.Session.flush()
self.Session.delete(purchase)
self.Session.flush()
def get_parent(self, item):
return item.purchase