Add initial Shopfoo pattern feature
data models, import/export, web views etc.
This commit is contained in:
parent
a7656928f5
commit
852f9d4902
46
rattail_demo/commands.py
Normal file
46
rattail_demo/commands.py
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
# -*- coding: utf-8; -*-
|
||||||
|
"""
|
||||||
|
Rattail Demo Commands
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from rattail import commands
|
||||||
|
from rattail_demo import __version__
|
||||||
|
|
||||||
|
|
||||||
|
def main(*args):
|
||||||
|
"""
|
||||||
|
Main entry point for Rattail Demo command system
|
||||||
|
"""
|
||||||
|
args = list(args or sys.argv[1:])
|
||||||
|
cmd = Command()
|
||||||
|
cmd.run(*args)
|
||||||
|
|
||||||
|
|
||||||
|
class Command(commands.Command):
|
||||||
|
"""
|
||||||
|
Main command for Rattail Demo
|
||||||
|
"""
|
||||||
|
name = 'rattail-demo'
|
||||||
|
version = __version__
|
||||||
|
description = "Rattail Demo (custom Rattail system)"
|
||||||
|
long_description = ""
|
||||||
|
|
||||||
|
|
||||||
|
class ExportShopfoo(commands.ExportFileSubcommand):
|
||||||
|
"""
|
||||||
|
Export data to the Shopfoo system
|
||||||
|
"""
|
||||||
|
name = 'export-shopfoo'
|
||||||
|
description = __doc__.strip()
|
||||||
|
handler_spec = 'rattail_demo.shopfoo.importing.rattail:FromRattailToShopfoo'
|
||||||
|
|
||||||
|
|
||||||
|
class ImportSelf(commands.ImportSubcommand):
|
||||||
|
"""
|
||||||
|
Update "cascading" Rattail data based on "core" Rattail data
|
||||||
|
"""
|
||||||
|
name = 'import-self'
|
||||||
|
description = __doc__.strip()
|
||||||
|
handler_spec = 'rattail_demo.importing.local:FromRattailDemoToSelf'
|
|
@ -20,4 +20,4 @@ class DemoConfigExtension(ConfigExtension):
|
||||||
config.setdefault('tailbone', 'menus', 'rattail_demo.web.menus')
|
config.setdefault('tailbone', 'menus', 'rattail_demo.web.menus')
|
||||||
|
|
||||||
# default import handlers
|
# default import handlers
|
||||||
config.setdefault('rattail.importing', 'versions.handler', 'rattail_corepos.importing.versions:FromRattailToRattailVersions')
|
config.setdefault('rattail.importing', 'versions.handler', 'rattail_demo.importing.versions:FromRattailDemoToRattailDemoVersions')
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""initial tables
|
||||||
|
|
||||||
|
Revision ID: 2108f9efa758
|
||||||
|
Revises: efb7cd318947
|
||||||
|
Create Date: 2020-08-19 20:02:15.501843
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '2108f9efa758'
|
||||||
|
down_revision = None
|
||||||
|
branch_labels = ('rattail_demo',)
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
import rattail.db.types
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
|
||||||
|
# demo_shopfoo_product
|
||||||
|
op.create_table('demo_shopfoo_product',
|
||||||
|
sa.Column('uuid', sa.String(length=32), nullable=False),
|
||||||
|
sa.Column('product_uuid', sa.String(length=32), nullable=True),
|
||||||
|
sa.Column('upc', sa.String(length=14), nullable=True),
|
||||||
|
sa.Column('description', sa.String(length=255), nullable=True),
|
||||||
|
sa.Column('price', sa.Numeric(precision=13, scale=2), nullable=True),
|
||||||
|
sa.Column('enabled', sa.Boolean(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['product_uuid'], ['product.uuid'], name='demo_shopfoo_product_fk_product'),
|
||||||
|
sa.PrimaryKeyConstraint('uuid')
|
||||||
|
)
|
||||||
|
op.create_table('demo_shopfoo_product_version',
|
||||||
|
sa.Column('uuid', sa.String(length=32), autoincrement=False, nullable=False),
|
||||||
|
sa.Column('product_uuid', sa.String(length=32), autoincrement=False, nullable=True),
|
||||||
|
sa.Column('upc', sa.String(length=14), autoincrement=False, nullable=True),
|
||||||
|
sa.Column('description', sa.String(length=255), autoincrement=False, nullable=True),
|
||||||
|
sa.Column('price', sa.Numeric(precision=13, scale=2), autoincrement=False, nullable=True),
|
||||||
|
sa.Column('enabled', sa.Boolean(), autoincrement=False, nullable=True),
|
||||||
|
sa.Column('transaction_id', sa.BigInteger(), autoincrement=False, nullable=False),
|
||||||
|
sa.Column('end_transaction_id', sa.BigInteger(), nullable=True),
|
||||||
|
sa.Column('operation_type', sa.SmallInteger(), nullable=False),
|
||||||
|
sa.PrimaryKeyConstraint('uuid', 'transaction_id')
|
||||||
|
)
|
||||||
|
op.create_index(op.f('ix_demo_shopfoo_product_version_end_transaction_id'), 'demo_shopfoo_product_version', ['end_transaction_id'], unique=False)
|
||||||
|
op.create_index(op.f('ix_demo_shopfoo_product_version_operation_type'), 'demo_shopfoo_product_version', ['operation_type'], unique=False)
|
||||||
|
op.create_index(op.f('ix_demo_shopfoo_product_version_transaction_id'), 'demo_shopfoo_product_version', ['transaction_id'], unique=False)
|
||||||
|
|
||||||
|
# demo_shopfoo_product_export
|
||||||
|
op.create_table('demo_shopfoo_product_export',
|
||||||
|
sa.Column('uuid', sa.String(length=32), nullable=False),
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('created', sa.DateTime(), nullable=False),
|
||||||
|
sa.Column('created_by_uuid', sa.String(length=32), nullable=False),
|
||||||
|
sa.Column('record_count', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('filename', sa.String(length=255), nullable=True),
|
||||||
|
sa.Column('uploaded', sa.Boolean(), nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(['created_by_uuid'], ['user.uuid'], name='demo_shopfoo_product_export_fk_created_by'),
|
||||||
|
sa.PrimaryKeyConstraint('uuid')
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
|
||||||
|
# demo_shopfoo_product_export
|
||||||
|
op.drop_table('demo_shopfoo_product_export')
|
||||||
|
|
||||||
|
# demo_shopfoo_product
|
||||||
|
op.drop_index(op.f('ix_demo_shopfoo_product_version_transaction_id'), table_name='demo_shopfoo_product_version')
|
||||||
|
op.drop_index(op.f('ix_demo_shopfoo_product_version_operation_type'), table_name='demo_shopfoo_product_version')
|
||||||
|
op.drop_index(op.f('ix_demo_shopfoo_product_version_end_transaction_id'), table_name='demo_shopfoo_product_version')
|
||||||
|
op.drop_table('demo_shopfoo_product_version')
|
||||||
|
op.drop_table('demo_shopfoo_product')
|
|
@ -8,3 +8,6 @@ from rattail.db.model import *
|
||||||
|
|
||||||
# also bring in CORE integration models
|
# also bring in CORE integration models
|
||||||
from rattail_corepos.db.model import *
|
from rattail_corepos.db.model import *
|
||||||
|
|
||||||
|
# now bring in Demo-specific models
|
||||||
|
from .shopfoo import ShopfooProduct, ShopfooProductExport
|
37
rattail_demo/db/model/shopfoo.py
Normal file
37
rattail_demo/db/model/shopfoo.py
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
# -*- coding: utf-8; -*-
|
||||||
|
"""
|
||||||
|
Database schema extensions for Shopfoo integration
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
from rattail.db import model
|
||||||
|
from rattail.db.model.shopfoo import ShopfooProductBase, ShopfooProductExportBase
|
||||||
|
|
||||||
|
|
||||||
|
class ShopfooProduct(ShopfooProductBase, model.Base):
|
||||||
|
"""
|
||||||
|
Shopfoo-specific product cache table. Each record in this table *should*
|
||||||
|
match exactly, what is in the actual "Shopfoo" system (even though that's
|
||||||
|
made-up in this case).
|
||||||
|
"""
|
||||||
|
__tablename__ = 'demo_shopfoo_product'
|
||||||
|
__versioned__ = {}
|
||||||
|
|
||||||
|
upc = sa.Column(sa.String(length=14), nullable=True)
|
||||||
|
|
||||||
|
description = sa.Column(sa.String(length=255), nullable=True)
|
||||||
|
|
||||||
|
price = sa.Column(sa.Numeric(precision=13, scale=2), nullable=True)
|
||||||
|
|
||||||
|
enabled = sa.Column(sa.Boolean(), nullable=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.description or self.upc or ""
|
||||||
|
|
||||||
|
|
||||||
|
class ShopfooProductExport(ShopfooProductExportBase, model.Base):
|
||||||
|
"""
|
||||||
|
Shopfoo product exports
|
||||||
|
"""
|
||||||
|
__tablename__ = 'demo_shopfoo_product_export'
|
6
rattail_demo/importing/__init__.py
Normal file
6
rattail_demo/importing/__init__.py
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Importing into Rattail Demo
|
||||||
|
"""
|
||||||
|
|
||||||
|
from . import model
|
60
rattail_demo/importing/local.py
Normal file
60
rattail_demo/importing/local.py
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
# -*- coding: utf-8; -*-
|
||||||
|
"""
|
||||||
|
Rattail Demo -> Rattail Demo "self" data import
|
||||||
|
"""
|
||||||
|
|
||||||
|
from rattail.importing.local import FromRattailLocalToRattail, FromRattailLocal
|
||||||
|
from rattail.importing.shopfoo import ShopfooProductImporterMixin
|
||||||
|
from rattail.util import OrderedDict
|
||||||
|
from rattail_demo import importing as rattail_demo_importing
|
||||||
|
|
||||||
|
|
||||||
|
class FromRattailDemoToSelf(FromRattailLocalToRattail):
|
||||||
|
"""
|
||||||
|
Handler for Rattail Demo -> Rattail Demo ("self") imports
|
||||||
|
"""
|
||||||
|
|
||||||
|
def get_importers(self):
|
||||||
|
importers = OrderedDict()
|
||||||
|
importers['ShopfooProduct'] = ShopfooProductImporter
|
||||||
|
return importers
|
||||||
|
|
||||||
|
|
||||||
|
class ShopfooProductImporter(ShopfooProductImporterMixin, FromRattailLocal, rattail_demo_importing.model.ShopfooProductImporter):
|
||||||
|
"""
|
||||||
|
Product -> ShopfooProduct
|
||||||
|
"""
|
||||||
|
supported_fields = [
|
||||||
|
'uuid',
|
||||||
|
'product_uuid',
|
||||||
|
'upc',
|
||||||
|
'description',
|
||||||
|
'price',
|
||||||
|
'enabled',
|
||||||
|
]
|
||||||
|
|
||||||
|
def normalize_base_product_data(self, product):
|
||||||
|
|
||||||
|
price = None
|
||||||
|
if product.regular_price:
|
||||||
|
price = product.regular_price.price
|
||||||
|
|
||||||
|
return {
|
||||||
|
'product_uuid': product.uuid,
|
||||||
|
'upc': str(product.upc or '') or None,
|
||||||
|
'description': product.full_description,
|
||||||
|
'price': price,
|
||||||
|
'enabled': True, # will maybe unset this in mark_unwanted()
|
||||||
|
}
|
||||||
|
|
||||||
|
def product_is_unwanted(self, product, data):
|
||||||
|
if super(ShopfooProductImporter, self).product_is_unwanted(product, data):
|
||||||
|
return True
|
||||||
|
if not data['price']: # let's say this is a required field for Shopfoo
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def mark_unwanted(self, product, data):
|
||||||
|
data = super(ShopfooProductImporter, self).mark_unwanted(product, data)
|
||||||
|
data['enabled'] = False
|
||||||
|
return data
|
18
rattail_demo/importing/model.py
Normal file
18
rattail_demo/importing/model.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# -*- coding: utf-8; -*-
|
||||||
|
"""
|
||||||
|
Rattail Demo model importers
|
||||||
|
"""
|
||||||
|
|
||||||
|
from rattail.importing.model import ToRattail
|
||||||
|
from rattail_demo.db import model
|
||||||
|
|
||||||
|
|
||||||
|
##############################
|
||||||
|
# custom models
|
||||||
|
##############################
|
||||||
|
|
||||||
|
class ShopfooProductImporter(ToRattail):
|
||||||
|
"""
|
||||||
|
Importer for ShopfooProduct data
|
||||||
|
"""
|
||||||
|
model_class = model.ShopfooProduct
|
25
rattail_demo/importing/versions.py
Normal file
25
rattail_demo/importing/versions.py
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# -*- coding: utf-8; -*-
|
||||||
|
"""
|
||||||
|
Rattail Demo -> Rattail Demo "versions" data import
|
||||||
|
"""
|
||||||
|
|
||||||
|
from rattail_demo.db import model
|
||||||
|
from rattail.importing import versions as base
|
||||||
|
from rattail_corepos.importing.versions import CoreposVersionMixin
|
||||||
|
|
||||||
|
|
||||||
|
class FromRattailDemoToRattailDemoVersions(base.FromRattailToRattailVersions,
|
||||||
|
CoreposVersionMixin):
|
||||||
|
"""
|
||||||
|
Handler for Rattail Demo -> Rattail Demo "versions" data import
|
||||||
|
"""
|
||||||
|
|
||||||
|
def get_importers(self):
|
||||||
|
importers = super(FromRattailDemoToRattailDemoVersions, self).get_importers()
|
||||||
|
importers = self.add_corepos_importers(importers)
|
||||||
|
importers['ShopfooProduct'] = ShopfooProductImporter
|
||||||
|
return importers
|
||||||
|
|
||||||
|
|
||||||
|
class ShopfooProductImporter(base.VersionImporter):
|
||||||
|
host_model_class = model.ShopfooProduct
|
0
rattail_demo/shopfoo/__init__.py
Normal file
0
rattail_demo/shopfoo/__init__.py
Normal file
6
rattail_demo/shopfoo/importing/__init__.py
Normal file
6
rattail_demo/shopfoo/importing/__init__.py
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Importing into Shopfoo
|
||||||
|
"""
|
||||||
|
|
||||||
|
from . import model
|
28
rattail_demo/shopfoo/importing/model.py
Normal file
28
rattail_demo/shopfoo/importing/model.py
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# -*- coding: utf-8; -*-
|
||||||
|
"""
|
||||||
|
Shopfoo model importers
|
||||||
|
"""
|
||||||
|
|
||||||
|
from rattail_demo.db import model
|
||||||
|
from rattail.importing.exporters import ToCSV
|
||||||
|
from rattail.shopfoo.importing.model import ProductImporterMixin
|
||||||
|
|
||||||
|
|
||||||
|
class ToShopfoo(ToCSV):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ProductImporter(ProductImporterMixin, ToShopfoo):
|
||||||
|
"""
|
||||||
|
Shopfoo product data importer
|
||||||
|
"""
|
||||||
|
key = 'uuid'
|
||||||
|
simple_fields = [
|
||||||
|
'uuid',
|
||||||
|
'product_uuid',
|
||||||
|
'upc',
|
||||||
|
'description',
|
||||||
|
'price',
|
||||||
|
'enabled',
|
||||||
|
]
|
||||||
|
export_model_class = model.ShopfooProductExport
|
62
rattail_demo/shopfoo/importing/rattail.py
Normal file
62
rattail_demo/shopfoo/importing/rattail.py
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
# -*- coding: utf-8; -*-
|
||||||
|
"""
|
||||||
|
Rattail -> Shopfoo importing
|
||||||
|
"""
|
||||||
|
|
||||||
|
from rattail import importing
|
||||||
|
from rattail.util import OrderedDict
|
||||||
|
|
||||||
|
from rattail_demo.db import model
|
||||||
|
from rattail_demo.shopfoo import importing as shopfoo_importing
|
||||||
|
from rattail.shopfoo.importing.rattail import ProductImporterMixin
|
||||||
|
|
||||||
|
|
||||||
|
class FromRattailToShopfoo(importing.FromRattailHandler):
|
||||||
|
"""
|
||||||
|
Rattail -> Shopfoo import handler
|
||||||
|
"""
|
||||||
|
host_title = "Rattail"
|
||||||
|
local_title = "Shopfoo"
|
||||||
|
direction = 'export'
|
||||||
|
|
||||||
|
def get_importers(self):
|
||||||
|
importers = OrderedDict()
|
||||||
|
importers['Product'] = ProductImporter
|
||||||
|
return importers
|
||||||
|
|
||||||
|
|
||||||
|
class FromRattail(importing.FromSQLAlchemy):
|
||||||
|
"""
|
||||||
|
Base class for Shopfoo -> Rattail importers
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class ProductImporter(ProductImporterMixin, FromRattail, shopfoo_importing.model.ProductImporter):
|
||||||
|
"""
|
||||||
|
Product data importer
|
||||||
|
"""
|
||||||
|
host_model_class = model.ShopfooProduct
|
||||||
|
supported_fields = [
|
||||||
|
'uuid',
|
||||||
|
'product_uuid',
|
||||||
|
'upc',
|
||||||
|
'description',
|
||||||
|
'price',
|
||||||
|
'enabled',
|
||||||
|
]
|
||||||
|
|
||||||
|
def query(self):
|
||||||
|
return self.host_session.query(model.ShopfooProduct)\
|
||||||
|
.order_by(model.ShopfooProduct.upc)
|
||||||
|
|
||||||
|
def normalize_host_object(self, product):
|
||||||
|
|
||||||
|
# copy all values "as-is" from our cache record
|
||||||
|
data = dict([(field, getattr(product, field))
|
||||||
|
for field in self.fields])
|
||||||
|
|
||||||
|
# TODO: is it ever a good idea to set this flag? doing so will mean
|
||||||
|
# the record is *not* included in CSV output file
|
||||||
|
# data['_deleted_'] = product.deleted_from_shopfoo
|
||||||
|
|
||||||
|
return data
|
|
@ -126,6 +126,22 @@ def simple_menus(request):
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
'title': "Shopfoo",
|
||||||
|
'type': 'menu',
|
||||||
|
'items': [
|
||||||
|
{
|
||||||
|
'title': "Products",
|
||||||
|
'url': url('shopfoo.products'),
|
||||||
|
'perm': 'shopfoo.products.list',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'title': "Product Exports",
|
||||||
|
'url': url('shopfoo.product_exports'),
|
||||||
|
'perm': 'shopfoo.product_exports.list',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
'title': "Batches",
|
'title': "Batches",
|
||||||
'type': 'menu',
|
'type': 'menu',
|
||||||
|
|
|
@ -37,6 +37,9 @@ def includeme(config):
|
||||||
# core-pos views
|
# core-pos views
|
||||||
config.include('tailbone_corepos.views.corepos')
|
config.include('tailbone_corepos.views.corepos')
|
||||||
|
|
||||||
|
# shopfoo views
|
||||||
|
config.include('rattail_demo.web.views.shopfoo')
|
||||||
|
|
||||||
# batch views
|
# batch views
|
||||||
config.include('tailbone.views.handheld')
|
config.include('tailbone.views.handheld')
|
||||||
config.include('tailbone.views.batch.inventory')
|
config.include('tailbone.views.batch.inventory')
|
||||||
|
|
9
rattail_demo/web/views/shopfoo/__init__.py
Normal file
9
rattail_demo/web/views/shopfoo/__init__.py
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# -*- coding: utf-8; -*-
|
||||||
|
"""
|
||||||
|
Shopfoo views
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def includeme(config):
|
||||||
|
config.include('rattail_demo.web.views.shopfoo.products')
|
||||||
|
config.include('rattail_demo.web.views.shopfoo.exports')
|
42
rattail_demo/web/views/shopfoo/exports.py
Normal file
42
rattail_demo/web/views/shopfoo/exports.py
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Views for Shopfoo product exports
|
||||||
|
"""
|
||||||
|
|
||||||
|
from rattail_demo.db import model
|
||||||
|
|
||||||
|
from tailbone.views.exports import ExportMasterView
|
||||||
|
|
||||||
|
|
||||||
|
class ShopfooProductExportView(ExportMasterView):
|
||||||
|
"""
|
||||||
|
Master view for Shopfoo product exports.
|
||||||
|
"""
|
||||||
|
model_class = model.ShopfooProductExport
|
||||||
|
route_prefix = 'shopfoo.product_exports'
|
||||||
|
url_prefix = '/shopfoo/exports/product'
|
||||||
|
downloadable = True
|
||||||
|
editable = True
|
||||||
|
delete_export_files = True
|
||||||
|
|
||||||
|
grid_columns = [
|
||||||
|
'id',
|
||||||
|
'created',
|
||||||
|
'created_by',
|
||||||
|
'filename',
|
||||||
|
'record_count',
|
||||||
|
'uploaded',
|
||||||
|
]
|
||||||
|
|
||||||
|
form_fields = [
|
||||||
|
'id',
|
||||||
|
'created',
|
||||||
|
'created_by',
|
||||||
|
'record_count',
|
||||||
|
'filename',
|
||||||
|
'uploaded',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def includeme(config):
|
||||||
|
ShopfooProductExportView.defaults(config)
|
70
rattail_demo/web/views/shopfoo/products.py
Normal file
70
rattail_demo/web/views/shopfoo/products.py
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
# -*- coding: utf-8; -*-
|
||||||
|
"""
|
||||||
|
Shopfoo product views
|
||||||
|
"""
|
||||||
|
|
||||||
|
from rattail_demo.db import model
|
||||||
|
|
||||||
|
from tailbone.views import MasterView
|
||||||
|
|
||||||
|
|
||||||
|
class ShopfooProductView(MasterView):
|
||||||
|
"""
|
||||||
|
Shopfoo Product views
|
||||||
|
"""
|
||||||
|
model_class = model.ShopfooProduct
|
||||||
|
url_prefix = '/shopfoo/products'
|
||||||
|
route_prefix = 'shopfoo.products'
|
||||||
|
creatable = False
|
||||||
|
editable = False
|
||||||
|
bulk_deletable = True
|
||||||
|
has_versions = True
|
||||||
|
|
||||||
|
labels = {
|
||||||
|
'upc': "UPC",
|
||||||
|
}
|
||||||
|
|
||||||
|
grid_columns = [
|
||||||
|
'upc',
|
||||||
|
'description',
|
||||||
|
'price',
|
||||||
|
'enabled',
|
||||||
|
]
|
||||||
|
|
||||||
|
form_fields = [
|
||||||
|
'product',
|
||||||
|
'upc',
|
||||||
|
'description',
|
||||||
|
'price',
|
||||||
|
'enabled',
|
||||||
|
]
|
||||||
|
|
||||||
|
def configure_grid(self, g):
|
||||||
|
super(ShopfooProductView, self).configure_grid(g)
|
||||||
|
|
||||||
|
g.filters['upc'].default_active = True
|
||||||
|
g.filters['upc'].default_verb = 'equal'
|
||||||
|
|
||||||
|
g.filters['description'].default_active = True
|
||||||
|
g.filters['description'].default_verb = 'contains'
|
||||||
|
|
||||||
|
g.set_sort_defaults('upc')
|
||||||
|
|
||||||
|
g.set_type('price', 'currency')
|
||||||
|
|
||||||
|
g.set_link('upc')
|
||||||
|
g.set_link('description')
|
||||||
|
|
||||||
|
def grid_extra_class(self, product, i):
|
||||||
|
if not product.enabled:
|
||||||
|
return 'warning'
|
||||||
|
|
||||||
|
def configure_form(self, f):
|
||||||
|
super(ShopfooProductView, self).configure_form(f)
|
||||||
|
|
||||||
|
f.set_renderer('product', self.render_product)
|
||||||
|
f.set_type('price', 'currency')
|
||||||
|
|
||||||
|
|
||||||
|
def includeme(config):
|
||||||
|
ShopfooProductView.defaults(config)
|
8
setup.py
8
setup.py
|
@ -89,5 +89,13 @@ setup(
|
||||||
'rattail.config.extensions': [
|
'rattail.config.extensions': [
|
||||||
'rattail-demo = rattail_demo.config:DemoConfigExtension',
|
'rattail-demo = rattail_demo.config:DemoConfigExtension',
|
||||||
],
|
],
|
||||||
|
'console_scripts': [
|
||||||
|
'rattail-demo = rattail_demo.commands:main',
|
||||||
|
],
|
||||||
|
|
||||||
|
'rattail_demo.commands': [
|
||||||
|
'export-shopfoo = rattail_demo.commands:ExportShopfoo',
|
||||||
|
'import-self = rattail_demo.commands:ImportSelf',
|
||||||
|
],
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue