This commit is contained in:
parent
e53b680dd2
commit
c8a6f6c209
13
db.py
13
db.py
|
@ -92,15 +92,16 @@ class Transaction(Base):
|
||||||
|
|
||||||
user = relationship(User, backref=backref('transactions', order_by=time))
|
user = relationship(User, backref=backref('transactions', order_by=time))
|
||||||
|
|
||||||
def __init__(self, user, amount=0, description=None, purchase=None):
|
def __init__(self, user, amount=0, description=None, purchase=None, penalty_ratio=1):
|
||||||
self.user = user
|
self.user = user
|
||||||
self.amount = amount
|
self.amount = amount
|
||||||
self.description = description
|
self.description = description
|
||||||
self.purchase = purchase
|
self.purchase = purchase
|
||||||
|
self.penalty_ratio = penalty_ratio
|
||||||
|
|
||||||
def perform_transaction(self):
|
def perform_transaction(self):
|
||||||
self.time = datetime.datetime.now()
|
self.time = datetime.datetime.now()
|
||||||
self.user.credit -= self.amount
|
self.user.credit -= self.amount * self.penalty_ratio
|
||||||
if self.purchase:
|
if self.purchase:
|
||||||
for entry in self.purchase.entries:
|
for entry in self.purchase.entries:
|
||||||
entry.product.stock -= entry.amount
|
entry.product.stock -= entry.amount
|
||||||
|
@ -111,12 +112,12 @@ class Purchase(Base):
|
||||||
|
|
||||||
id = Column(Integer, primary_key=True)
|
id = Column(Integer, primary_key=True)
|
||||||
time = Column(DateTime)
|
time = Column(DateTime)
|
||||||
# user_name = Column(Integer, ForeignKey('users.name'))
|
# user_name = Column(Integer, ForeignKey('users.name'))
|
||||||
price = Column(Integer)
|
price = Column(Integer)
|
||||||
# performed = Column(Boolean)
|
# performed = Column(Boolean)
|
||||||
|
|
||||||
# user = relationship(User, backref=backref('purchases', order_by=id))
|
# user = relationship(User, backref=backref('purchases', order_by=id))
|
||||||
# users = relationship(User, secondary=purchase_user, backref='purhcases'
|
# users = relationship(User, secondary=purchase_user, backref='purhcases'
|
||||||
transactions = relationship(Transaction, order_by=Transaction.user_name, backref='purchase')
|
transactions = relationship(Transaction, order_by=Transaction.user_name, backref='purchase')
|
||||||
entries = relationship(PurchaseEntry, backref=backref("purchase"))
|
entries = relationship(PurchaseEntry, backref=backref("purchase"))
|
||||||
|
|
||||||
|
|
229
text_based.py
229
text_based.py
|
@ -5,9 +5,11 @@ import sqlalchemy
|
||||||
from sqlalchemy.sql import func
|
from sqlalchemy.sql import func
|
||||||
from sqlalchemy import desc
|
from sqlalchemy import desc
|
||||||
import re, sys, os, traceback, signal, readline
|
import re, sys, os, traceback, signal, readline
|
||||||
|
from select import select
|
||||||
from helpers import *
|
from helpers import *
|
||||||
import random
|
import random
|
||||||
from statistikkHelpers import statisticsTextOnly
|
from statistikkHelpers import statisticsTextOnly
|
||||||
|
from math import ceil
|
||||||
|
|
||||||
random.seed()
|
random.seed()
|
||||||
exit_commands = ['exit', 'abort', 'quit', 'bye', 'eat flaming death', 'q']
|
exit_commands = ['exit', 'abort', 'quit', 'bye', 'eat flaming death', 'q']
|
||||||
|
@ -93,7 +95,9 @@ class Menu():
|
||||||
return self.items[i]
|
return self.items[i]
|
||||||
|
|
||||||
def input_str(self, prompt=None, regex=None, length_range=(None,None),
|
def input_str(self, prompt=None, regex=None, length_range=(None,None),
|
||||||
empty_string_is_none=False):
|
empty_string_is_none=False, timeout=0):
|
||||||
|
if prompt == None:
|
||||||
|
prompt = self.prompt
|
||||||
if regex != None:
|
if regex != None:
|
||||||
while True:
|
while True:
|
||||||
result = self.input_str(prompt, length_range=length_range,
|
result = self.input_str(prompt, length_range=length_range,
|
||||||
|
@ -119,8 +123,14 @@ class Menu():
|
||||||
print 'Value must have length at most %d' % length_range[1]
|
print 'Value must have length at most %d' % length_range[1]
|
||||||
else:
|
else:
|
||||||
return result
|
return result
|
||||||
if prompt == None:
|
if timeout != 0:
|
||||||
prompt = self.prompt
|
print prompt,
|
||||||
|
rlist, _, _ = select([sys.stdin], [], [], timeout)
|
||||||
|
if rlist:
|
||||||
|
s = sys.stdin.readline()
|
||||||
|
return s
|
||||||
|
else:
|
||||||
|
return ''
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
result = unicode(raw_input(safe_str(prompt)),
|
result = unicode(raw_input(safe_str(prompt)),
|
||||||
|
@ -274,7 +284,6 @@ class Menu():
|
||||||
return (result,num)
|
return (result,num)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def search_for_thing(self, search_str, permitted_things=('user','product'),
|
def search_for_thing(self, search_str, permitted_things=('user','product'),
|
||||||
add_nonexisting=()):
|
add_nonexisting=()):
|
||||||
search_fun = {'user': search_user,
|
search_fun = {'user': search_user,
|
||||||
|
@ -349,7 +358,7 @@ class Menu():
|
||||||
print 'No %ss matching "%s"' % (thing, search_str)
|
print 'No %ss matching "%s"' % (thing, search_str)
|
||||||
return None
|
return None
|
||||||
if len(result) == 1:
|
if len(result) == 1:
|
||||||
msg = 'One %s matching "%s": %s. Use this?' %\
|
msg = 'One %s matching "%s": %s. Use this?' % \
|
||||||
(thing, search_str, unicode(result[0]))
|
(thing, search_str, unicode(result[0]))
|
||||||
if self.confirm(msg, default=True):
|
if self.confirm(msg, default=True):
|
||||||
return result[0]
|
return result[0]
|
||||||
|
@ -369,8 +378,8 @@ class Menu():
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def confirm(self, prompt, default=None):
|
def confirm(self, prompt, default=None, timeout=0):
|
||||||
return ConfirmMenu(prompt, default).execute()
|
return ConfirmMenu(prompt, default, timeout).execute()
|
||||||
|
|
||||||
def print_header(self):
|
def print_header(self):
|
||||||
print
|
print
|
||||||
|
@ -465,15 +474,16 @@ class Selector(Menu):
|
||||||
|
|
||||||
|
|
||||||
class ConfirmMenu(Menu):
|
class ConfirmMenu(Menu):
|
||||||
def __init__(self, prompt='confirm?', default=None):
|
def __init__(self, prompt='confirm?', default=None, timeout=0):
|
||||||
Menu.__init__(self, 'question', prompt=prompt,
|
Menu.__init__(self, 'question', prompt=prompt,
|
||||||
exit_disallowed_msg='Please answer yes or no')
|
exit_disallowed_msg='Please answer yes or no')
|
||||||
self.default=default
|
self.default=default
|
||||||
|
self.timeout=0
|
||||||
|
|
||||||
def _execute(self):
|
def _execute(self):
|
||||||
options = {True: '[y]/n', False: 'y/[n]', None: 'y/n'}[self.default]
|
options = {True: '[y]/n', False: 'y/[n]', None: 'y/n'}[self.default]
|
||||||
while True:
|
while True:
|
||||||
result = self.input_str('%s (%s) ' % (self.prompt, options))
|
result = self.input_str('%s (%s) ' % (self.prompt, options), timeout=self.timeout)
|
||||||
result = result.lower()
|
result = result.lower()
|
||||||
if result in ['y','yes']:
|
if result in ['y','yes']:
|
||||||
return True
|
return True
|
||||||
|
@ -503,39 +513,39 @@ class FAQMenu(Menu):
|
||||||
Menu.__init__(self, 'Frequently Asked Questions')
|
Menu.__init__(self, 'Frequently Asked Questions')
|
||||||
self.items = [MessageMenu('What is the meaning with this program?',
|
self.items = [MessageMenu('What is the meaning with this program?',
|
||||||
'''
|
'''
|
||||||
We want to avoid keeping lots of cash in PVVVV\'s money box and to
|
We want to avoid keeping lots of cash in PVVVV\'s money box and to
|
||||||
make it easy to pay for stuff without using money. (Without using
|
make it easy to pay for stuff without using money. (Without using
|
||||||
money each time, that is. You do of course have to pay for the things
|
money each time, that is. You do of course have to pay for the things
|
||||||
you buy eventually).
|
you buy eventually).
|
||||||
|
|
||||||
Dibbler stores a "credit" amount for each user. When you register a
|
Dibbler stores a "credit" amount for each user. When you register a
|
||||||
purchase in Dibbler, this amount is decreased. To increase your
|
purchase in Dibbler, this amount is decreased. To increase your
|
||||||
credit, add money to the money box and use "Adjust credit" to tell
|
credit, add money to the money box and use "Adjust credit" to tell
|
||||||
Dibbler about it.
|
Dibbler about it.
|
||||||
'''),
|
'''),
|
||||||
MessageMenu('Can I still pay for stuff using cash?',
|
MessageMenu('Can I still pay for stuff using cash?',
|
||||||
'Yes. You can safely ignore this program completely.'),
|
'Yes. You can safely ignore this program completely.'),
|
||||||
MessageMenu('How do I exit from a submenu/dialog/thing?',
|
MessageMenu('How do I exit from a submenu/dialog/thing?',
|
||||||
'Type "exit" or C-d.'),
|
'Type "exit" or C-d.'),
|
||||||
MessageMenu('What does "." mean?',
|
MessageMenu('What does "." mean?',
|
||||||
'''
|
'''
|
||||||
The "." character, known as "full stop" or "period", is most often
|
The "." character, known as "full stop" or "period", is most often
|
||||||
used to indicate the end of a sentence.
|
used to indicate the end of a sentence.
|
||||||
|
|
||||||
It is also used by Dibbler to indicate that the program wants you to
|
It is also used by Dibbler to indicate that the program wants you to
|
||||||
read some text before continuing. Whenever some output ends with a
|
read some text before continuing. Whenever some output ends with a
|
||||||
line containing only a period, you should read the lines above and
|
line containing only a period, you should read the lines above and
|
||||||
then press enter to continue.
|
then press enter to continue.
|
||||||
'''),
|
'''),
|
||||||
MessageMenu('Why is the user interface so terribly unintuitive?',
|
MessageMenu('Why is the user interface so terribly unintuitive?',
|
||||||
'''
|
'''
|
||||||
Answer #1: It is not.
|
Answer #1: It is not.
|
||||||
|
|
||||||
Answer #2: We are trying to compete with PVV\'s microwave oven in
|
Answer #2: We are trying to compete with PVV\'s microwave oven in
|
||||||
userfriendliness.
|
userfriendliness.
|
||||||
|
|
||||||
Answer #3: YOU are unintuitive.
|
Answer #3: YOU are unintuitive.
|
||||||
'''),
|
'''),
|
||||||
MessageMenu('Why is there no help command?',
|
MessageMenu('Why is there no help command?',
|
||||||
'There is. Have you tried typing "help"?'),
|
'There is. Have you tried typing "help"?'),
|
||||||
MessageMenu('Where are the easter eggs? I tried saying "moo", but nothing happened.',
|
MessageMenu('Where are the easter eggs? I tried saying "moo", but nothing happened.',
|
||||||
|
@ -544,54 +554,54 @@ Answer #3: YOU are unintuitive.
|
||||||
u'Godt spørsmål. Det virket sikkert som en god idé der og da.'),
|
u'Godt spørsmål. Det virket sikkert som en god idé der og da.'),
|
||||||
MessageMenu('I found a bug; is there a reward?',
|
MessageMenu('I found a bug; is there a reward?',
|
||||||
'''
|
'''
|
||||||
No.
|
No.
|
||||||
|
|
||||||
But if you are certain that it is a bug, not a feature, then you
|
But if you are certain that it is a bug, not a feature, then you
|
||||||
should fix it (or better: force someone else to do it).
|
should fix it (or better: force someone else to do it).
|
||||||
|
|
||||||
Follow this procedure:
|
Follow this procedure:
|
||||||
|
|
||||||
1. Check out the Dibbler code from https://dev.pvv.ntnu.no/svn/dibbler
|
1. Check out the Dibbler code from https://dev.pvv.ntnu.no/svn/dibbler
|
||||||
|
|
||||||
2. Fix the bug.
|
2. Fix the bug.
|
||||||
|
|
||||||
3. Check that the program still runs (and, preferably, that the bug is
|
3. Check that the program still runs (and, preferably, that the bug is
|
||||||
in fact fixed).
|
in fact fixed).
|
||||||
|
|
||||||
4. Commit.
|
4. Commit.
|
||||||
|
|
||||||
5. Update the running copy from svn:
|
5. Update the running copy from svn:
|
||||||
|
|
||||||
$ su -
|
$ su -
|
||||||
# su -l -s /bin/bash pvvvv
|
# su -l -s /bin/bash pvvvv
|
||||||
$ cd dibbler
|
$ cd dibbler
|
||||||
$ svn up
|
$ svn up
|
||||||
|
|
||||||
6. Type "restart" in Dibbler to replace the running process by a new
|
6. Type "restart" in Dibbler to replace the running process by a new
|
||||||
one using the updated files.
|
one using the updated files.
|
||||||
'''),
|
'''),
|
||||||
MessageMenu('My question isn\'t listed here; what do I do?',
|
MessageMenu('My question isn\'t listed here; what do I do?',
|
||||||
'''
|
'''
|
||||||
DON\'T PANIC.
|
DON\'T PANIC.
|
||||||
|
|
||||||
Follow this procedure:
|
Follow this procedure:
|
||||||
|
|
||||||
1. Ask someone (or read the source code) and get an answer.
|
1. Ask someone (or read the source code) and get an answer.
|
||||||
|
|
||||||
2. Check out the Dibbler code from https://dev.pvv.ntnu.no/svn/dibbler
|
2. Check out the Dibbler code from https://dev.pvv.ntnu.no/svn/dibbler
|
||||||
|
|
||||||
3. Add your question (with answer) to the FAQ and commit.
|
3. Add your question (with answer) to the FAQ and commit.
|
||||||
|
|
||||||
4. Update the running copy from svn:
|
4. Update the running copy from svn:
|
||||||
|
|
||||||
$ su -
|
$ su -
|
||||||
# su -l -s /bin/bash pvvvv
|
# su -l -s /bin/bash pvvvv
|
||||||
$ cd dibbler
|
$ cd dibbler
|
||||||
$ svn up
|
$ svn up
|
||||||
|
|
||||||
5. Type "restart" in Dibbler to replace the running process by a new
|
5. Type "restart" in Dibbler to replace the running process by a new
|
||||||
one using the updated files.
|
one using the updated files.
|
||||||
''')]
|
''')]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -857,6 +867,47 @@ addition, and you can type 'what' at any time to redisplay it.
|
||||||
|
|
||||||
When finished, write an empty line to confirm the purchase.
|
When finished, write an empty line to confirm the purchase.
|
||||||
'''
|
'''
|
||||||
|
def credit_check(self, user):
|
||||||
|
"""
|
||||||
|
|
||||||
|
:param user:
|
||||||
|
:type user: User
|
||||||
|
:rtype: boolean
|
||||||
|
"""
|
||||||
|
assert isinstance(user, User)
|
||||||
|
|
||||||
|
return user.credit > low_credit_warning_limit
|
||||||
|
|
||||||
|
def low_credit_warning(self, user, timeout=False):
|
||||||
|
assert isinstance(user, User)
|
||||||
|
|
||||||
|
print "***********************************************************************"
|
||||||
|
print "***********************************************************************"
|
||||||
|
print
|
||||||
|
print "$$\ $$\ $$$$$$\ $$$$$$$\ $$\ $$\ $$$$$$\ $$\ $$\ $$$$$$\\"
|
||||||
|
print "$$ | $\ $$ |$$ __$$\ $$ __$$\ $$$\ $$ |\_$$ _|$$$\ $$ |$$ __$$\\"
|
||||||
|
print "$$ |$$$\ $$ |$$ / $$ |$$ | $$ |$$$$\ $$ | $$ | $$$$\ $$ |$$ / \__|"
|
||||||
|
print "$$ $$ $$\$$ |$$$$$$$$ |$$$$$$$ |$$ $$\$$ | $$ | $$ $$\$$ |$$ |$$$$\\"
|
||||||
|
print "$$$$ _$$$$ |$$ __$$ |$$ __$$< $$ \$$$$ | $$ | $$ \$$$$ |$$ |\_$$ |"
|
||||||
|
print "$$$ / \$$$ |$$ | $$ |$$ | $$ |$$ |\$$$ | $$ | $$ |\$$$ |$$ | $$ |"
|
||||||
|
print "$$ / \$$ |$$ | $$ |$$ | $$ |$$ | \$$ |$$$$$$\ $$ | \$$ |\$$$$$$ |"
|
||||||
|
print "\__/ \__|\__| \__|\__| \__|\__| \__|\______|\__| \__| \______/"
|
||||||
|
print
|
||||||
|
print "***********************************************************************"
|
||||||
|
print "***********************************************************************"
|
||||||
|
print
|
||||||
|
print "USER %s HAS LOWER CREDIT THAN %d." % (user.name, low_credit_warning_limit)
|
||||||
|
print "THIS PURCHASE WILL CHARGE YOUR CREDIT TWICE AS MUCH."
|
||||||
|
print "CONSIDER PUTTING MONEY IN THE BOX TO AVOID THIS."
|
||||||
|
print
|
||||||
|
print "Do you want to continue with this purchase?"
|
||||||
|
|
||||||
|
if timeout:
|
||||||
|
print "THIS PURCHASE WILL AUTOMATICALLY BE PERFORMED IN 3 MINUTES!"
|
||||||
|
return self.confirm(prompt=">", default=True, timeout=180)
|
||||||
|
else:
|
||||||
|
return self.confirm(prompt=">")
|
||||||
|
|
||||||
|
|
||||||
def add_thing_to_purchase(self, thing):
|
def add_thing_to_purchase(self, thing):
|
||||||
if isinstance(thing, User):
|
if isinstance(thing, User):
|
||||||
|
@ -865,6 +916,13 @@ When finished, write an empty line to confirm the purchase.
|
||||||
print 'You are now purchasing as the user anonym.'
|
print 'You are now purchasing as the user anonym.'
|
||||||
print 'You have to put money in the anonym-jar.'
|
print 'You have to put money in the anonym-jar.'
|
||||||
print '--------------------------------------------'
|
print '--------------------------------------------'
|
||||||
|
|
||||||
|
if not self.credit_check(thing):
|
||||||
|
if self.low_credit_warning(thing, self.superfast_mode ):
|
||||||
|
Transaction(thing, purchase=self.purchase, penalty_ratio=2)
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
Transaction(thing, purchase=self.purchase)
|
Transaction(thing, purchase=self.purchase)
|
||||||
elif isinstance(thing, Product):
|
elif isinstance(thing, Product):
|
||||||
PurchaseEntry(self.purchase, thing, 1)
|
PurchaseEntry(self.purchase, thing, 1)
|
||||||
|
@ -1006,6 +1064,46 @@ class AdjustStockMenu(Menu):
|
||||||
print 'The stock is now %d' % (product.stock)
|
print 'The stock is now %d' % (product.stock)
|
||||||
|
|
||||||
|
|
||||||
|
class CleanupStockMenu(Menu):
|
||||||
|
def __init__(self):
|
||||||
|
Menu.__init__(self,'Stock Cleanup', uses_db=True)
|
||||||
|
|
||||||
|
def _execute(self):
|
||||||
|
self.print_header()
|
||||||
|
|
||||||
|
products = self.session.query(Product).filter(Product.stock != 0).all()
|
||||||
|
|
||||||
|
print "Every product in stock will be printed."
|
||||||
|
print "Entering no value will keep current stock or set it to 0 if it is negative."
|
||||||
|
print "Entering a value will set current stock to that value."
|
||||||
|
print "Press enter to begin."
|
||||||
|
|
||||||
|
self.pause()
|
||||||
|
|
||||||
|
changed_products = []
|
||||||
|
|
||||||
|
for product in products:
|
||||||
|
oldstock = product.stock
|
||||||
|
product.stock = self.input_int(product.name, (0,10000), default=max(0, oldstock))
|
||||||
|
self.session.add(product)
|
||||||
|
if oldstock != product.stock:
|
||||||
|
changed_products.append((product, oldstock))
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.session.commit()
|
||||||
|
print 'New stocks are now stored.'
|
||||||
|
self.pause()
|
||||||
|
except sqlalchemy.exc.SQLAlchemyError, e:
|
||||||
|
print 'Could not store stock: %s' % (e)
|
||||||
|
self.pause()
|
||||||
|
return
|
||||||
|
|
||||||
|
for p in changed_products:
|
||||||
|
print p[0].name, ".", p[1], "->", p[0].stock
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class AdjustCreditMenu(Menu): # reimplements ChargeMenu; these should be combined to one
|
class AdjustCreditMenu(Menu): # reimplements ChargeMenu; these should be combined to one
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Menu.__init__(self, 'Adjust credit', uses_db=True)
|
Menu.__init__(self, 'Adjust credit', uses_db=True)
|
||||||
|
@ -1078,14 +1176,14 @@ class ProductPopularityMenu(Menu):
|
||||||
text = ''
|
text = ''
|
||||||
sub = \
|
sub = \
|
||||||
self.session.query(PurchaseEntry.product_bar_code,
|
self.session.query(PurchaseEntry.product_bar_code,
|
||||||
func.count('*').label('purchase_count'))\
|
func.count('*').label('purchase_count')) \
|
||||||
.group_by(PurchaseEntry.product_bar_code)\
|
.group_by(PurchaseEntry.product_bar_code) \
|
||||||
.subquery()
|
.subquery()
|
||||||
product_list = \
|
product_list = \
|
||||||
self.session.query(Product, sub.c.purchase_count)\
|
self.session.query(Product, sub.c.purchase_count) \
|
||||||
.outerjoin((sub, Product.bar_code==sub.c.product_bar_code))\
|
.outerjoin((sub, Product.bar_code==sub.c.product_bar_code)) \
|
||||||
.order_by(desc(sub.c.purchase_count))\
|
.order_by(desc(sub.c.purchase_count)) \
|
||||||
.filter(sub.c.purchase_count != None)\
|
.filter(sub.c.purchase_count != None) \
|
||||||
.all()
|
.all()
|
||||||
line_format = '%10s | %-'+str(Product.name_length)+'s\n'
|
line_format = '%10s | %-'+str(Product.name_length)+'s\n'
|
||||||
text += line_format % ('items sold', 'product')
|
text += line_format % ('items sold', 'product')
|
||||||
|
@ -1103,14 +1201,14 @@ class ProductRevenueMenu(Menu):
|
||||||
text = ''
|
text = ''
|
||||||
sub = \
|
sub = \
|
||||||
self.session.query(PurchaseEntry.product_bar_code,
|
self.session.query(PurchaseEntry.product_bar_code,
|
||||||
func.count('*').label('purchase_count'))\
|
func.count('*').label('purchase_count')) \
|
||||||
.group_by(PurchaseEntry.product_bar_code)\
|
.group_by(PurchaseEntry.product_bar_code) \
|
||||||
.subquery()
|
.subquery()
|
||||||
product_list = \
|
product_list = \
|
||||||
self.session.query(Product, sub.c.purchase_count)\
|
self.session.query(Product, sub.c.purchase_count) \
|
||||||
.outerjoin((sub, Product.bar_code==sub.c.product_bar_code))\
|
.outerjoin((sub, Product.bar_code==sub.c.product_bar_code)) \
|
||||||
.order_by(desc(sub.c.purchase_count*Product.price))\
|
.order_by(desc(sub.c.purchase_count*Product.price)) \
|
||||||
.filter(sub.c.purchase_count != None)\
|
.filter(sub.c.purchase_count != None) \
|
||||||
.all()
|
.all()
|
||||||
line_format = '%7s | %10s | %5s | %-'+str(Product.name_length)+'s\n'
|
line_format = '%7s | %10s | %5s | %-'+str(Product.name_length)+'s\n'
|
||||||
text += line_format % ('revenue', 'items sold', 'price', 'product')
|
text += line_format % ('revenue', 'items sold', 'price', 'product')
|
||||||
|
@ -1244,8 +1342,8 @@ much money you're due in credits for the purchase when prompted.
|
||||||
print ('\n%-'+str(Product.name_length-1)+'s Amount') % ("Product")
|
print ('\n%-'+str(Product.name_length-1)+'s Amount') % ("Product")
|
||||||
print (6+Product.name_length)*'-'
|
print (6+Product.name_length)*'-'
|
||||||
if len(self.products):
|
if len(self.products):
|
||||||
# print "Products added:"
|
# print "Products added:"
|
||||||
# print (6+Product.name_length)*'-'
|
# print (6+Product.name_length)*'-'
|
||||||
for product in self.products.keys():
|
for product in self.products.keys():
|
||||||
print ('%'+str(-Product.name_length)+'s %5i') % (product.name, self.products[product])
|
print ('%'+str(-Product.name_length)+'s %5i') % (product.name, self.products[product])
|
||||||
print (6+Product.name_length)*'-'
|
print (6+Product.name_length)*'-'
|
||||||
|
@ -1265,7 +1363,7 @@ much money you're due in credits for the purchase when prompted.
|
||||||
self.products[thing] = amount
|
self.products[thing] = amount
|
||||||
|
|
||||||
def perform_transaction(self):
|
def perform_transaction(self):
|
||||||
# self.user.credit += self.price
|
# self.user.credit += self.price
|
||||||
description = self.input_str('Log message> ', length_range=(0,50))
|
description = self.input_str('Log message> ', length_range=(0,50))
|
||||||
if description == '':
|
if description == '':
|
||||||
description = 'Purchased products for PVVVV, adjusted credit '+str(self.price)
|
description = 'Purchased products for PVVVV, adjusted credit '+str(self.price)
|
||||||
|
@ -1277,7 +1375,7 @@ much money you're due in credits for the purchase when prompted.
|
||||||
try:
|
try:
|
||||||
self.session.commit()
|
self.session.commit()
|
||||||
print "Success! Transaction performed:"
|
print "Success! Transaction performed:"
|
||||||
# self.print_info()
|
# self.print_info()
|
||||||
print "User %s's credit is now %i" % (self.user.name, self.user.credit)
|
print "User %s's credit is now %i" % (self.user.name, self.user.credit)
|
||||||
except sqlalchemy.exc.SQLAlchemyError, e:
|
except sqlalchemy.exc.SQLAlchemyError, e:
|
||||||
print 'Could not perform transaction: %s' % e
|
print 'Could not perform transaction: %s' % e
|
||||||
|
@ -1298,7 +1396,8 @@ main = MainMenu('Dibbler main menu',
|
||||||
EditUserMenu(),
|
EditUserMenu(),
|
||||||
AddProductMenu(),
|
AddProductMenu(),
|
||||||
EditProductMenu(),
|
EditProductMenu(),
|
||||||
AdjustStockMenu(),]),
|
AdjustStockMenu(),
|
||||||
|
CleanupStockMenu(),]),
|
||||||
ProductSearchMenu(),
|
ProductSearchMenu(),
|
||||||
Menu('Statistics',
|
Menu('Statistics',
|
||||||
items=[ProductPopularityMenu(),
|
items=[ProductPopularityMenu(),
|
||||||
|
|
Loading…
Reference in New Issue