tailbone/rattail/pyramid/views/products.py

332 lines
11 KiB
Python
Raw Normal View History

2012-04-10 12:39:30 -05:00
#!/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 <http://www.gnu.org/licenses/>.
#
################################################################################
"""
``rattail.pyramid.views.products`` -- Product Views
"""
from webhelpers.html import literal
2012-08-01 07:54:03 -05:00
from webhelpers.html.tags import link_to
2012-08-01 09:58:56 -05:00
from sqlalchemy.orm import joinedload
from edbob.pyramid.filters import filter_ilike
from edbob.pyramid.grids import sorter
from edbob.pyramid.views import GridView
from edbob.pyramid.views.crud import Crud
2012-04-10 12:39:30 -05:00
2012-08-01 07:54:03 -05:00
import edbob
from edbob.pyramid import Session
2012-04-10 12:39:30 -05:00
import rattail
2012-08-01 07:54:03 -05:00
import rattail.labels
from rattail.pyramid.forms import (UpcFieldRenderer, PriceFieldRenderer,
PriceWithExpirationFieldRenderer)
class ProductGrid(GridView):
mapped_class = rattail.Product
route_name = 'products.list'
route_prefix = 'product'
def join_map(self):
return {
'brand':
lambda q: q.outerjoin(rattail.Brand),
'department':
2012-08-01 09:58:56 -05:00
lambda q: q.outerjoin(rattail.Department,
rattail.Department.uuid == rattail.Product.department_uuid),
2012-08-01 09:58:56 -05:00
'subdepartment':
lambda q: q.outerjoin(rattail.Subdepartment,
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):
return self.make_filter_map(
exact=['upc'],
ilike=['description', 'size'],
brand=filter_ilike(rattail.Brand.name),
2012-08-01 09:58:56 -05:00
department=filter_ilike(rattail.Department.name),
subdepartment=filter_ilike(rattail.Subdepartment.name))
def search_config(self, fmap):
return self.make_search_config(
fmap,
include_filter_upc=True,
filter_type_upc='eq',
include_filter_brand=True,
filter_type_brand='lk',
include_filter_description=True,
filter_type_description='lk',
include_filter_department=True,
filter_type_department='lk')
def search_form(self, config):
return self.make_search_form(
config, upc="UPC")
def grid_config(self, search, fmap):
kwargs = {}
if self.request.has_perm('products.delete'):
kwargs['deletable'] = True
return self.make_grid_config(
search, fmap, sort='description', **kwargs)
def sort_map(self):
return self.make_sort_map(
'upc', 'description', 'size',
brand=sorter(rattail.Brand.name),
2012-08-01 09:58:56 -05:00
department=sorter(rattail.Department.name),
subdepartment=sorter(rattail.Subdepartment.name),
regular_price=sorter(rattail.ProductPrice.price),
current_price=sorter(rattail.ProductPrice.price))
2012-08-01 09:58:56 -05:00
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))
2012-08-01 09:58:56 -05:00
return q
def grid(self, data, config):
g = self.make_grid(data, config)
g.upc.set(renderer=UpcFieldRenderer)
g.regular_price.set(renderer=PriceFieldRenderer)
g.current_price.set(renderer=PriceWithExpirationFieldRenderer)
g.configure(
include=[
g.upc.label("UPC"),
g.brand,
g.description,
g.size,
2012-08-01 09:58:56 -05:00
# g.department,
g.subdepartment,
g.regular_price.label("Reg. Price"),
g.current_price.label(literal("Cur. Price&nbsp; (Exp.)")),
],
readonly=True)
2012-08-01 07:54:03 -05:00
def callback(prod):
return link_to("Print", '#', class_='print-label')
if edbob.config.getboolean('rattail.labels', 'enabled', default=False):
g.add_column('labels', "Labels", callback)
return g
class ProductCrud(Crud):
mapped_class = rattail.Product
home_route = 'products.list'
def fieldset(self, obj):
fs = self.make_fieldset(obj)
fs.configure(
include=[
fs.description,
])
return fs
2012-04-16 00:51:12 -05:00
2012-08-01 07:54:03 -05:00
def print_label(request):
profile = request.params.get('profile')
profile = rattail.labels.get_profile(profile) if profile else None
assert profile
uuid = request.params.get('uuid')
product = Session.query(rattail.Product).get(uuid) if uuid else None
assert product
quantity = request.params.get('quantity')
assert quantity.isdigit()
quantity = int(quantity)
printer = profile.get_printer()
printer.print_labels([(product, quantity)])
return {}
2012-04-10 12:39:30 -05:00
def includeme(config):
ProductGrid.add_route(config, 'products.list', '/products')
ProductCrud.add_routes(config)
2012-08-01 07:54:03 -05:00
config.add_route('products.print_label', '/products/label')
config.add_view(print_label, route_name='products.print_label', renderer='json')
# from sqlalchemy.orm import joinedload
# import transaction
# from pyramid.httpexceptions import HTTPFound
# from pyramid.view import view_config
# from edbob.pyramid import filters
# from edbob.pyramid import forms
# from edbob.pyramid import grids
# from edbob.pyramid import Session
# import rattail
# from rattail.batches import next_batch_id
# from rattail.pyramid import util
# from rattail.pyramid.forms import UpcFieldRenderer
# def filter_map():
# return filters.get_filter_map(
# rattail.Product,
# exact=['upc'],
# ilike=['description', 'size'],
# department=filters.filter_ilike(rattail.Department.name),
# brand=filters.filter_ilike(rattail.Brand.name))
# def search_config(request, fmap):
# return filters.get_search_config(
# 'products.list', request, fmap,
# include_filter_brand=True,
# filter_type_brand='lk',
# include_filter_description=True,
# filter_type_description='lk',
# include_filter_department=True,
# filter_type_department='lk')
# def search_form(config):
# return filters.get_search_form(
# config, upc="UPC")
# def grid_config(request, search, fmap):
# return grids.get_grid_config(
# 'products.list', request, search,
# filter_map=fmap, sort='description')
# def sort_map():
# return grids.get_sort_map(
# rattail.Product,
# ['upc', 'description', 'size'],
# department=grids.sorter(rattail.Department.name),
# brand=grids.sorter(rattail.Brand.name))
# def query(config):
# jmap = {
# 'department': lambda q: q.outerjoin(rattail.Department),
# 'brand': lambda q: q.outerjoin(rattail.Brand),
# }
# smap = sort_map()
# q = Session.query(rattail.Product)
# q = q.options(joinedload(rattail.Product.department))
# q = q.options(joinedload(rattail.Product.brand))
# q = filters.filter_query(q, config, jmap)
# q = grids.sort_query(q, config, smap, jmap)
# return q
# @view_config(route_name='products.list', renderer='/products/index.mako')
# def products(context, request):
# fmap = filter_map()
# config = search_config(request, fmap)
# search = search_form(config)
# config = grid_config(request, search, fmap)
# products = grids.get_pager(query, config)
# g = forms.AlchemyGrid(
# rattail.Product, products, config,
# gridurl=request.route_url('products.list'))
# g.configure(
# include=[
# g.upc.with_renderer(UpcFieldRenderer).label("UPC"),
# g.brand,
# g.description,
# g.size,
# g.department,
# ],
# readonly=True)
# grid = g.render(class_='clickable products')
# return grids.render_grid(request, grid, search)
# @view_config(route_name='products.batch')
# def batch(context, request):
# fmap = filter_map()
# config = search_config(request, fmap)
# search = search_form(config)
# config = grid_config(request, search, fmap)
# products = query(config)
# home = HTTPFound(location=request.route_url('products.list'))
# source = util.get_terminal('rattail')
# if not source:
# return home
# dct = util.get_dictionary('ITEM_DCT')
# if not dct:
# return home
# with transaction.manager:
# batch = rattail.Batch()
# Session.add(batch)
# batch.source = source
# batch.source_description = source.description
# batch.batch_id = next_batch_id(source.sil_id, consume=True,
# session=Session())
# batch.name = '%s.%08u' % (source.sil_id, batch.batch_id)
# batch.dictionary = dct
# batch.action_type = rattail.BATCH_ADD
# batch.description = "products from Rattail"
# for i, col in enumerate(source.source_columns(dct), 1):
# batch.columns.append(rattail.BatchColumn(
# ordinal=i,
# sil_column=col.sil_column,
# source=source,
# targeted=True,
# ))
# batch.create_table()
# batch.add_rows(source, dct, query=products)
# batch.rowcount = products.count()
# url = request.route_url('batch.edit', uuid=batch.uuid)
# return HTTPFound(location=url)
# def includeme(config):
# config.add_route('products.list', '/products')
# config.add_route('products.batch', '/products/batch')
# config.scan(__name__)