This commit is contained in:
parent
e53b680dd2
commit
c8a6f6c209
5
db.py
5
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
|
||||||
|
|
117
text_based.py
117
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,
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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