http://www.youtube.com/watch?v=xW5xOdDk-BE

Here are the steps:


# let us go into our web2py folder
cd /Users/mdipierro/Desktop/demo/web2py

# and we create a new app called pos (point of sale)
cd applications
mkdir pos
rm -r pos/*

# we make it a clone of the scaffolding application
cp -r welcome/* pos/
cd pos

open http://127.0.0.1:8000/admin/default/design/welcome

# lets get janrain working!
edit models/db.py
# -*- coding: utf-8 -*-
# this file is released under public domain and you can use without
limitations

#########################################################################
## This scaffolding model makes your app work on Google App Engine too
#########################################################################

if request.env.web2py_runtime_gae:            # if running on Google
App Engine
    db = DAL('gae')                           # connect to Google
BigTable
                                              # optional DAL('gae://
namespace')
    session.connect(request, response, db = db) # and store sessions
and tickets there
    ### or use the following lines to store sessions in Memcache
    # from gluon.contrib.memdb import MEMDB
    # from google.appengine.api.memcache import Client
    # session.connect(request, response, db = MEMDB(Client()))
else:                                         # else use a normal
relational database
    db = DAL('sqlite://storage.sqlite')       # if not, use SQLite or
other DB
## if no need for session
# session.forget()

#########################################################################
## Here is sample code if you need for
## - email capabilities
## - authentication (registration, login, logout, ... )
## - authorization (role based authorization)
## - services (xml, csv, json, xmlrpc, jsonrpc, amf, rss)
## - crud actions
## (more options discussed in gluon/tools.py)
#########################################################################

from gluon.tools import *
mail = Mail()                                  # mailer
auth = Auth(globals(),db)                      # authentication/
authorization
crud = Crud(globals(),db)                      # for CRUD helpers
using auth
service = Service(globals())                   # for json, xml,
jsonrpc, xmlrpc, amfrpc
plugins = PluginManager()

mail.settings.server = 'logging' or 'smtp.gmail.com:587'  # your SMTP
server
mail.settings.sender = 'y...@gmail.com'         # your email
mail.settings.login = 'username:password'      # your credentials or
None

auth.settings.hmac_key = '<your secret key>'   # before
define_tables()
auth.define_tables()                           # creates all needed
tables
auth.settings.mailer = mail                    # for user email
verification
auth.settings.registration_requires_verification = False
auth.settings.registration_requires_approval = False
auth.messages.verify_email = 'Click on the link
http://'+request.env.http_host+URL('default','user',args=['verify_email'])+'/%(key)s
to verify your email'
auth.settings.reset_password_requires_verification = True
auth.messages.reset_password = 'Click on the link
http://'+request.env.http_host+URL('default','user',args=['reset_password'])+'/%(key)s
to reset your password'

#########################################################################
## If you need to use OpenID, Facebook, MySpace, Twitter, Linkedin,
etc.
## register with janrain.com, uncomment and customize following
from gluon.contrib.login_methods.rpx_account import RPXAccount
auth.settings.actions_disabled=['register','change_password','request_reset_password']
api_key = open('/Users/mdipierro/
janrain_api_key.txt','r').read().strip()
auth.settings.login_form = RPXAccount(request,
api_key=api_key,domain='web2py',
    url = "http://localhost:8000/%s/default/user/login"; %
request.application)
## other login methods are in gluon/contrib/login_methods
#########################################################################

crud.settings.auth = None                      # =auth to enforce
authorization on crud
@@END@@

open http://127.0.0.1:8000/admin/default/peek/welcome/models/db.py

# then we create a custom model
edit models/db_pos.py
# we need a table to store products
db.define_table('product',
   Field('name',notnull=True,unique=True),
   Field('price','double'),
   Field('description','text'),
   Field('image','upload'),
   Field('sortable','integer'),
   auth.signature,
   format='%(name)s')

# and one table to store sales of products to users
db.define_table('sale',
   Field('invoice'),
   Field('creditcard'),
   Field('buyer',db.auth_user),
   Field('product',db.product),
   Field('quantity','integer'),
   Field('price','double'),
   Field('shipped','boolean',default=False),
   auth.signature),

# we also make a session cart, just in case
session.cart = session.cart or {}
@@END@@

# we can now already access the model via app-admin
# try create some products
open http://127.0.0.1:8000/pos/appadmin

# we can also create prducts programmatically here is one way
mkdir private
cd private
#  let's get an image
wget 
http://www.clker.com/cliparts/5/1/9/a/11954319101307220149molumen_cardboard_box.svg.med.png
sh:convert 11954319101307220149molumen_cardboard_box.svg.med.png
box.jpg
open box.jpg
cd ..
edit private/script.py
import os

# find the box
path = os.path.join(request.folder,'private','box.jpg')

# insert it in a database record
id = db.product.insert(name='Box',price=2.99,description='the best
box',
 
image=db.product.image.store(open(path,'rb'),path))
print 'record created, id=',id

# and do not forget to commit
db.commit()
@@END@@

# now let's run it
cd ../..
python web2py.py -S pos -M -N -R applications/pos/private/script.py
cd applications/pos

# let us write a controller with the actions we need
rm controllers/default.py
edit controllers/default.py
# list of products
def index():
   products = db(db.product).select(orderby=db.product.sortable)
   return locals()

# login, registration, etcetera
def user():
    return dict(form=auth())

# an action to download uploaded images
def download():
    return response.download(request,db)

# an action to expose web services
def call():
    session.forget()
    return service()
@@END@@

# let us try listing the products we created
open http://127.0.0.1:8000/pos/default/index

# let us make this better by creating a view
rm views/default/index.html
edit views/default/index.html
{{extend 'layout.html'}}
<h1>Products</h1>
{{for p in products:}}
  <div>
    <h2>{{=p.name}} - ${{=p.price}}</h2>
    <img src="{{=URL('download',args=p.image)}}" align="right"/>
    {{=MARKMIN(p.description)}}
  </div>
{{pass}}
@@END@@

open http://127.0.0.1:8000/pos/default/index

# and we make a simple menu
edit models/menu.py
response.menu=[
   (T('Home'),False,URL('default','index')),
   (T('Cart'),False,URL('default','cart')),
   (T('Buy'),False,URL('default','buy')),
]
@@END@@

open http://127.0.0.1:8000/pos/default/index

# now we create some more logic for our app
edit controllers/default.py
# list of products
def index():
   products = db(db.product).select(orderby=db.product.sortable)
   return locals()

# login, registration, etcetera
def user():
    return dict(form=auth())

# an action to download uploaded images
def download():
    return response.download(request,db)

# an action to expose web services
def call():
    session.forget()
    return service()

# an action to see and process a shopping cart
@auth.requires_login()
def cart():
    return dict(cart=session.cart)

# this is for paying
@auth.requires_login()
def pay():
    form = SQLFORM.factory(Field('creditcard'))
    if form.accepts(request,session):
        for key, value in session.cart.items():
            db.sale.insert(buyer=auth.user.id,
                           product = key,
                           quantity = value,
                           price = db.product(key).price,
                           creditcard = form.vars.creditcard)
        session.cart.clear()
        session.flash = 'Thank you for your order'
        redirect(URL('index'))
    return dict(cart=session.cart,form=form)

# an action to add and remove items from the shopping cart
def cart_callback():
    id = int(request.vars.id)
    if request.vars.action == 'add':
        session.cart[id]=session.cart.get(id,0)+1
    if request.vars.action == 'sub':
        session.cart[id]=max(0,session.cart.get(id,0)-1)
    return str(session.cart[id])
@@END@@

# we add a button from the index page
edit views/default/index.html
{{extend 'layout.html'}}
<h1>Products</h1>
{{for p in products:}}
  <div>
    <h2>{{=p.name}} - ${{=p.price}}</h2>
    <img src="{{=URL('download',args=p.image)}}" align="right"/>
    {{=MARKMIN(p.description)}}
    <span id="item{{=p.id}}">{{=session.cart.get(p.id,0)}}</span> in
cart - <button
onclick="ajax('{{=URL('cart_callback',vars=dict(id=p.id,action='add'))}}',
[],'item{{=p.id}}')">add to cart</button>
  </div>
{{pass}}
@@END@@

# and a view for the cart so visitors can see their products
edit views/default/cart.html
{{extend 'layout.html'}}
<h1>Your Shopping Cart</h1>
<table width="100%">
  {{for id, qty in cart.items():}}{{p=db.product(id)}}
  <tr>
    <td>{{=p.name}}</td>
    <td>${{=p.price}}</td>
    <td id="item{{=id}}">{{=qty}}</td>
    <td><button
onclick="ajax('{{=URL('cart_callback',vars=dict(id=p.id,action='add'))}}',
[],'item{{=id}}')">add</button></td>
    <td><button
onclick="ajax('{{=URL('cart_callback',vars=dict(id=p.id,action='sub'))}}',
[],'item{{=id}}')">sub</button></td>
  </tr>
  {{pass}}
</table>
<a href="{{=URL('pay')}}">checkout</a>
@@END@@

# and a view for the buy action
edit views/default/pay.html
{{extend 'layout.html'}}
<h1>Checkout</h1>
{{=form}}
@@END@@

# now try to add something to your cart and buy the products
open http://127.0.0.1:8000/pos

# Let's change the layout
wget 
http://web2py.com/layouts/static/plugin_layouts/plugins/web2py.plugin.layout_Commission.w2p
tar zxvf web2py.plugin.layout_Commission.w2p

# time to accept real payments
edit models/aim.py
from gluon.contrib.AuthorizeNet import AIM

def process(creditcard,expiration,total,cvv,tax,invoice):
    payment = AIM('cnpdev4289', 'SR2P8g4jdEn7vFLQ', True)
    payment.setTransaction(creditcard, expiration.replace('/',''),
total, cvv, tax, invoice)
    payment.process()
    return payment.isApproved()
@@END@@

# check out the new layout
open http://127.0.0.1:8000/pos

edit controllers/default.py
# list of products
def index():
   products = db(db.product).select(orderby=db.product.sortable)
   return locals()

# login, registration, etcetera
def user():
    return dict(form=auth())

# an action to download uploaded images
def download():
    return response.download(request,db)

# an action to expose web services
def call():
    session.forget()
    return service()


# an action to see and process a shopping cart
@auth.requires_login()
def cart():
    return dict(cart=session.cart)

# time to pay ... now for real
@auth.requires_login()
def pay():
    import uuid
    invoice = str(uuid.uuid4())
    total = sum(db.product(id).price*qty for id,qty in
session.cart.items())
    form =
SQLFORM.factory(Field('creditcard',default='4427802641004797'),
                           Field('expiration',default='12/2012'),
                           Field('cvv',default='123'),
                           Field('total','double',default=total,writable=False))

    if form.accepts(request,session):
        if process(form.vars.creditcard,form.vars.expiration,
                   total,form.vars.cvv,0.0,'invoice'):
            for key, value in session.cart.items():
                db.sale.insert(invoice=invoice,
                               buyer=auth.user.id,
                               product = key,
                               quantity = value,
                               price = db.product(key).price,
                               creditcard = form.vars.creditcard)
            session.cart.clear()
            session.flash = 'Thank you for your order'
            redirect(URL('index'))
        else:
            response.flash = "payment rejected (please call XXX)"
    return dict(cart=session.cart,form=form)

# an action to add and remove items from the shopping cart
def cart_callback():
    id = int(request.vars.id)
    if request.vars.action == 'add':
        session.cart[id]=session.cart.get(id,0)+1
    if request.vars.action == 'sub':
        session.cart[id]=max(0,session.cart.get(id,0)-1)
    return str(session.cart[id])
@@END@@

# done. now we have a functional web store

Reply via email to