From 1ade5940460d84697a72f1d9d3715b087e369e93 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sat, 17 Aug 2013 08:36:56 -0700 Subject: [PATCH] Overhauled report views to allow easier template customization. --- rattail/pyramid/views/reports.py | 254 ++++++++++++++++--------------- 1 file changed, 131 insertions(+), 123 deletions(-) diff --git a/rattail/pyramid/views/reports.py b/rattail/pyramid/views/reports.py index 327eef52..2cb4d307 100644 --- a/rattail/pyramid/views/reports.py +++ b/rattail/pyramid/views/reports.py @@ -23,22 +23,19 @@ ################################################################################ """ -``rattail.pyramid.views.reports`` -- Report Views +Report Views """ -import os -import os.path -import re - +from .core import View from mako.template import Template - from pyramid.response import Response -import edbob -from edbob.time import local_time - -import rattail from rattail.pyramid import Session +from rattail.db import Vendor, Department, Product, ProductCost + +import re +import rattail +from edbob.time import local_time from rattail.files import resource_path @@ -56,134 +53,145 @@ def get_upc(product): return upc -def inventory_report(request): - """ - This is the "Inventory Worksheet" report. - """ - - departments = Session.query(rattail.Department) - - if request.params.get('department'): - department = departments.get(request.params['department']) - if department: - body = write_inventory_worksheet(request, department) - response = Response(content_type='text/html') - response.headers['Content-Length'] = len(body) - response.headers['Content-Disposition'] = 'attachment; filename=inventory.html' - response.text = body - return response - - departments = departments.order_by(rattail.Department.name) - departments = departments.all() - return{'departments': departments} - - -def write_inventory_worksheet(request, department): - """ - Generates the Inventory Worksheet report. - """ - - def get_products(subdepartment): - q = Session.query(rattail.Product) - q = q.outerjoin(rattail.Brand) - q = q.filter(rattail.Product.subdepartment == subdepartment) - if request.params.get('weighted-only'): - q = q.filter(rattail.Product.unit_of_measure == rattail.UNIT_OF_MEASURE_POUND) - q = q.order_by(rattail.Brand.name, rattail.Product.description) - return q.all() - - now = local_time() - data = dict( - date=now.strftime('%a %d %b %Y'), - time=now.strftime('%I:%M %p'), - department=department, - get_products=get_products, - get_upc=get_upc, - ) - - report = resource_path('rattail.pyramid:reports/inventory_worksheet.mako') - template = Template(filename=report) - return template.render(**data) - - -def ordering_report(request): +class OrderingWorksheet(View): """ This is the "Ordering Worksheet" report. """ - if request.params.get('vendor'): - vendor = Session.query(rattail.Vendor).get(request.params['vendor']) - if vendor: - departments = [] - uuids = request.params.get('departments') - if uuids: - for uuid in uuids.split(','): - dept = Session.query(rattail.Department).get(uuid) - if dept: - departments.append(dept) - preferred_only = request.params.get('preferred_only') == '1' - body = write_ordering_worksheet(vendor, departments, preferred_only) - response = Response(content_type='text/html') - response.headers['Content-Length'] = len(body) - response.headers['Content-Disposition'] = 'attachment; filename=ordering.html' - response.text = body - return response - return {} + report_template_path = 'rattail.pyramid:reports/ordering_worksheet.mako' + + upc_getter = staticmethod(get_upc) + + def __call__(self): + if self.request.params.get('vendor'): + vendor = Session.query(Vendor).get(self.request.params['vendor']) + if vendor: + departments = [] + uuids = self.request.params.get('departments') + if uuids: + for uuid in uuids.split(','): + dept = Session.query(Department).get(uuid) + if dept: + departments.append(dept) + preferred_only = self.request.params.get('preferred_only') == '1' + body = self.write_report(vendor, departments, preferred_only) + response = Response(content_type='text/html') + response.headers['Content-Length'] = len(body) + response.headers['Content-Disposition'] = 'attachment; filename=ordering.html' + response.text = body + return response + return {} + + def write_report(self, vendor, departments, preferred_only): + """ + Rendering engine for the ordering worksheet report. + """ + + q = Session.query(ProductCost) + q = q.join(Product) + q = q.filter(ProductCost.vendor == vendor) + q = q.filter(Product.department_uuid.in_([x.uuid for x in departments])) + if preferred_only: + q = q.filter(ProductCost.preference == 1) + + costs = {} + for cost in q: + dept = cost.product.department + subdept = cost.product.subdepartment + costs.setdefault(dept, {}) + costs[dept].setdefault(subdept, []) + costs[dept][subdept].append(cost) + + def cost_sort_key(cost): + product = cost.product + brand = product.brand.name if product.brand else '' + key = '{0} {1}'.format(brand, product.description) + return key + + now = local_time() + data = dict( + vendor=vendor, + costs=costs, + cost_sort_key=cost_sort_key, + date=now.strftime('%a %d %b %Y'), + time=now.strftime('%I:%M %p'), + get_upc=self.upc_getter, + rattail=rattail, + ) + + template_path = resource_path(self.report_template_path) + template = Template(filename=template_path) + return template.render(**data) -def write_ordering_worksheet(vendor, departments, preferred_only): +class InventoryWorksheet(View): """ - Rendering engine for the ordering worksheet report. + This is the "Inventory Worksheet" report. """ - q = Session.query(rattail.ProductCost) - q = q.join(rattail.Product) - q = q.filter(rattail.ProductCost.vendor == vendor) - q = q.filter(rattail.Product.department_uuid.in_([x.uuid for x in departments])) - if preferred_only: - q = q.filter(rattail.ProductCost.preference == 1) + report_template_path = 'rattail.pyramid:reports/inventory_worksheet.mako' - costs = {} - for cost in q: - dept = cost.product.department - subdept = cost.product.subdepartment - costs.setdefault(dept, {}) - costs[dept].setdefault(subdept, []) - costs[dept][subdept].append(cost) + upc_getter = staticmethod(get_upc) - def cost_sort_key(cost): - product = cost.product - brand = product.brand.name if product.brand else '' - key = '{0} {1}'.format(brand, product.description) - return key + def __call__(self): + """ + This is the "Inventory Worksheet" report. + """ - now = local_time() - data = dict( - vendor=vendor, - costs=costs, - cost_sort_key=cost_sort_key, - date=now.strftime('%a %d %b %Y'), - time=now.strftime('%I:%M %p'), - get_upc=get_upc, - rattail=rattail, - ) + departments = Session.query(Department) - report = resource_path('rattail.pyramid:reports/ordering_worksheet.mako') - report = edbob.config.get('rattail.pyramid', 'report.ordering_worksheet', - default=report) - report = os.path.abspath(report) - template = Template(filename=report) - return template.render(**data) + if self.request.params.get('department'): + department = departments.get(self.request.params['department']) + if department: + body = self.write_report(department) + response = Response(content_type='text/html') + response.headers['Content-Length'] = len(body) + response.headers['Content-Disposition'] = 'attachment; filename=inventory.html' + response.text = body + return response + + departments = departments.order_by(rattail.Department.name) + departments = departments.all() + return{'departments': departments} + + def write_report(self, department): + """ + Generates the Inventory Worksheet report. + """ + + def get_products(subdepartment): + q = Session.query(rattail.Product) + q = q.outerjoin(rattail.Brand) + q = q.filter(rattail.Product.subdepartment == subdepartment) + if self.request.params.get('weighted-only'): + q = q.filter(rattail.Product.unit_of_measure == rattail.UNIT_OF_MEASURE_POUND) + q = q.order_by(rattail.Brand.name, rattail.Product.description) + return q.all() + + now = local_time() + data = dict( + date=now.strftime('%a %d %b %Y'), + time=now.strftime('%I:%M %p'), + department=department, + get_products=get_products, + get_upc=self.upc_getter, + ) + + template_path = resource_path(self.report_template_path) + template = Template(filename=template_path) + return template.render(**data) + + +def add_routes(config): + config.add_route('reports.ordering', '/reports/ordering') + config.add_route('reports.inventory', '/reports/inventory') def includeme(config): + add_routes(config) - config.add_route('reports.inventory', '/reports/inventory') - config.add_view(inventory_report, - route_name='reports.inventory', - renderer='/reports/inventory.mako') - - config.add_route('reports.ordering', '/reports/ordering') - config.add_view(ordering_report, - route_name='reports.ordering', + config.add_view(OrderingWorksheet, route_name='reports.ordering', renderer='/reports/ordering.mako') + + config.add_view(InventoryWorksheet, route_name='reports.inventory', + renderer='/reports/inventory.mako')