From 165538c8f17a5208d9ef128571ce3cb781776391 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Thu, 2 Aug 2012 10:44:25 -0700 Subject: [PATCH] add Vendor views, update Product views for new pricing changes --- rattail/pyramid/forms.py | 61 +++-------- rattail/pyramid/templates/products/index.mako | 4 +- rattail/pyramid/templates/vendors/base.mako | 2 + rattail/pyramid/templates/vendors/index.mako | 6 ++ rattail/pyramid/views/__init__.py | 1 + rattail/pyramid/views/products.py | 27 +++-- rattail/pyramid/views/vendors.py | 100 ++++++++++++++++++ 7 files changed, 146 insertions(+), 55 deletions(-) create mode 100644 rattail/pyramid/templates/vendors/base.mako create mode 100644 rattail/pyramid/templates/vendors/index.mako create mode 100644 rattail/pyramid/views/vendors.py diff --git a/rattail/pyramid/forms.py b/rattail/pyramid/forms.py index 7f9f4bae..c042dbf4 100644 --- a/rattail/pyramid/forms.py +++ b/rattail/pyramid/forms.py @@ -58,54 +58,27 @@ class BatchIdFieldRenderer(formalchemy.FieldRenderer): # def render(self, options, **kwargs): -class PriceFieldRenderer(formalchemy.fields.FloatFieldRenderer): +class PriceFieldRenderer(formalchemy.FieldRenderer): """ - Generic renderer for price (currency) fields. + Renderer for fields which reference a :class:`ProductPrice` instance. """ def render_readonly(self, **kwargs): - value = self.raw_value - if value is None: - return '' - return '$ %0.2f' % value - - -class RegularPriceFieldRenderer(PriceFieldRenderer): - """ - Custom renderer for the :attr:`rattail.Product.regular_price` field. - """ - - def render_readonly(self, **kwargs): - prod = self.field.model - - if prod.regular_price and prod.package_price: - return '$ %0.2f  ($ %0.2f / %u)' % ( - prod.regular_price, prod.package_price, prod.package_price_quantity) - - elif prod.regular_price: - return '$ %0.2f' % prod.regular_price - - elif prod.package_price: - return '$ %0.2f / %u' % ( - prod.package_price, prod.package_price_quantity) - - return '' - - -class SalePriceFieldRenderer(PriceFieldRenderer): - """ - Custom renderer for the :attr:`rattail.Product.sale_price` field. - """ - - def render_readonly(self, **kwargs): - prod = self.field.model - - if prod.sale_price: - if prod.sale_price_quantity and prod.sale_price_quantity != 1: - return '$ %0.2f / %u' % ( - prod.sale_price, prod.sale_price_quantity) - return '$ %0.2f' % prod.sale_price - + price = self.field.raw_value + if price: + if price.price is not None and price.pack_price is not None: + if price.multiple > 1: + return '$ %0.2f / %u  ($ %0.2f / %u)' % ( + price.price, price.multiple, + price.pack_price, price.pack_multiple) + return '$ %0.2f  ($ %0.2f / %u)' % ( + price.price, price.pack_price, price.pack_multiple) + if price.price is not None: + if price.multiple > 1: + return '$ %0.2f / %u' % (price.price, price.multiple) + return '$ %0.2f' % price.price + if price.pack_price is not None: + return '$ %0.2f / %u' % (price.pack_price, price.pack_multiple) return '' diff --git a/rattail/pyramid/templates/products/index.mako b/rattail/pyramid/templates/products/index.mako index 10f43824..faba2e9e 100644 --- a/rattail/pyramid/templates/products/index.mako +++ b/rattail/pyramid/templates/products/index.mako @@ -23,8 +23,8 @@ } div.grid.Product table tbody td.size, - div.grid.Product table tbody td.regular_price, - div.grid.Product table tbody td.sale_price { + div.grid.Product table tbody td.regular_price_uuid, + div.grid.Product table tbody td.current_price_uuid { padding-right: 6px; text-align: right; } diff --git a/rattail/pyramid/templates/vendors/base.mako b/rattail/pyramid/templates/vendors/base.mako new file mode 100644 index 00000000..27f7dd90 --- /dev/null +++ b/rattail/pyramid/templates/vendors/base.mako @@ -0,0 +1,2 @@ +<%inherit file="/base.mako" /> +${parent.body()} diff --git a/rattail/pyramid/templates/vendors/index.mako b/rattail/pyramid/templates/vendors/index.mako new file mode 100644 index 00000000..1e637857 --- /dev/null +++ b/rattail/pyramid/templates/vendors/index.mako @@ -0,0 +1,6 @@ +<%inherit file="/vendors/base.mako" /> +<%inherit file="/index.mako" /> + +<%def name="title()">Vendors + +${parent.body()} diff --git a/rattail/pyramid/views/__init__.py b/rattail/pyramid/views/__init__.py index dcdd7996..86bc1d47 100644 --- a/rattail/pyramid/views/__init__.py +++ b/rattail/pyramid/views/__init__.py @@ -33,3 +33,4 @@ def includeme(config): config.include('rattail.pyramid.views.categories') config.include('rattail.pyramid.views.products') config.include('rattail.pyramid.views.employees') + config.include('rattail.pyramid.views.vendors') diff --git a/rattail/pyramid/views/products.py b/rattail/pyramid/views/products.py index ba07e1c7..737cf4b4 100644 --- a/rattail/pyramid/views/products.py +++ b/rattail/pyramid/views/products.py @@ -40,8 +40,7 @@ from edbob.pyramid import Session import rattail import rattail.labels -from rattail.pyramid.forms import ( - UpcFieldRenderer, RegularPriceFieldRenderer, SalePriceFieldRenderer) +from rattail.pyramid.forms import UpcFieldRenderer, PriceFieldRenderer class ProductGrid(GridView): @@ -56,10 +55,16 @@ class ProductGrid(GridView): lambda q: q.outerjoin(rattail.Brand), 'department': lambda q: q.outerjoin(rattail.Department, - rattail.Product.department_uuid == rattail.Department.uuid), + rattail.Department.uuid == rattail.Product.department_uuid), 'subdepartment': lambda q: q.outerjoin(rattail.Subdepartment, - rattail.Product.subdepartment_uuid == rattail.Subdepartment.uuid), + rattail.Subdepartment.uuid == rattail.Product.subdepartment_uuid), + 'regular_price': + lambda q: q.outerjoin(rattail.ProductPrice, + rattail.ProductPrice.uuid == rattail.Product.regular_price_uuid), + 'current_price': + lambda q: q.outerjoin(rattail.ProductPrice, + rattail.ProductPrice.uuid == rattail.Product.current_price_uuid), } def filter_map(self): @@ -95,23 +100,27 @@ class ProductGrid(GridView): def sort_map(self): return self.make_sort_map( - 'upc', 'description', 'size', 'regular_price', 'sale_price', + 'upc', 'description', 'size', brand=sorter(rattail.Brand.name), department=sorter(rattail.Department.name), - subdepartment=sorter(rattail.Subdepartment.name)) + subdepartment=sorter(rattail.Subdepartment.name), + regular_price=sorter(rattail.ProductPrice.price), + current_price=sorter(rattail.ProductPrice.price)) def query(self, config): q = self.make_query(config) q = q.options(joinedload(rattail.Product.department)) q = q.options(joinedload(rattail.Product.subdepartment)) q = q.options(joinedload(rattail.Product.brand)) + q = q.options(joinedload(rattail.Product.regular_price)) + q = q.options(joinedload(rattail.Product.current_price)) return q def grid(self, data, config): g = self.make_grid(data, config) g.upc.set(renderer=UpcFieldRenderer) - g.regular_price.set(renderer=RegularPriceFieldRenderer) - g.sale_price.set(renderer=SalePriceFieldRenderer) + g.regular_price.set(renderer=PriceFieldRenderer) + g.current_price.set(renderer=PriceFieldRenderer) g.configure( include=[ g.upc.label("UPC"), @@ -121,7 +130,7 @@ class ProductGrid(GridView): # g.department, g.subdepartment, g.regular_price.label("Reg Price"), - g.sale_price.label("Sale Price"), + g.current_price.label("Cur Price"), ], readonly=True) diff --git a/rattail/pyramid/views/vendors.py b/rattail/pyramid/views/vendors.py new file mode 100644 index 00000000..6b278bd5 --- /dev/null +++ b/rattail/pyramid/views/vendors.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +################################################################################ +# +# Rattail -- Retail Software Framework +# Copyright © 2010-2012 Lance Edgar +# +# This file is part of Rattail. +# +# Rattail is free software: you can redistribute it and/or modify it under the +# terms of the GNU Affero General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) +# any later version. +# +# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for +# more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Rattail. If not, see . +# +################################################################################ + +""" +``rattail.pyramid.views.vendors`` -- Vendor Views +""" + +from edbob.pyramid.views import GridView, AutocompleteView +from edbob.pyramid.views.crud import Crud + +import rattail + + +class VendorGrid(GridView): + + mapped_class = rattail.Vendor + route_name = 'vendors.list' + route_prefix = 'vendor' + + def filter_map(self): + return self.make_filter_map( + exact=['id'], + ilike=['name']) + + def search_config(self, fmap): + return self.make_search_config( + fmap, + include_filter_name=True, + filter_type_name='lk') + + def search_form(self, config): + return self.make_search_form(config, id="ID") + + def grid_config(self, search, fmap): + kwargs = {} + if self.request.has_perm('vendors.delete'): + kwargs['deletable'] = True + return self.make_grid_config( + search, fmap, sort='name', **kwargs) + + def sort_map(self): + return self.make_sort_map('id', 'name') + + def grid(self, data, config): + g = self.make_grid(data, config) + g.configure( + include=[ + g.id.label("ID"), + g.name, + ], + readonly=True) + return g + + +class VendorCrud(Crud): + + mapped_class = rattail.Vendor + home_route = 'vendors.list' + + def fieldset(self, obj): + fs = self.make_fieldset(obj) + fs.configure( + include=[ + fs.id, + fs.name, + ]) + return fs + + +class VendorAutocomplete(AutocompleteView): + + mapped_class = rattail.Vendor + fieldname = 'name' + + +def includeme(config): + VendorGrid.add_route(config, 'vendors.list', '/vendors') + VendorCrud.add_routes(config) + VendorAutocomplete.add_route(config)