Implement to-go logic for all, none, or previous

This commit is contained in:
Sebastian Pipping 2011-10-10 07:33:13 +02:00
parent cf5cae5303
commit fafb03c843
3 changed files with 108 additions and 7 deletions

View File

@ -6,7 +6,7 @@
from __future__ import print_function from __future__ import print_function
import freitagslib.network as net import freitagslib.network as net
from freitagslib.commands import BuyCommand, DepositCommand from freitagslib.commands import BuyCommand, DepositCommand, ToGoCommand
import colorama import colorama
from colorama import Fore, Style from colorama import Fore, Style
@ -22,6 +22,7 @@ import urllib2
COLOR_WARN = Fore.YELLOW COLOR_WARN = Fore.YELLOW
COLOR_ERROR = Fore.RED COLOR_ERROR = Fore.RED
COLOR_DEPOSIT = Fore.GREEN + Style.BRIGHT COLOR_DEPOSIT = Fore.GREEN + Style.BRIGHT
COLOR_TO_GO = Fore.MAGENTA + Style.BRIGHT
COLOR_WITHDRAW = Fore.RED + Style.BRIGHT COLOR_WITHDRAW = Fore.RED + Style.BRIGHT
COLOR_SOME = Fore.WHITE + Style.BRIGHT COLOR_SOME = Fore.WHITE + Style.BRIGHT
@ -34,10 +35,18 @@ def clear():
os.system('clear') os.system('clear')
TO_GO_ALL = 1
TO_GO_NONE = 0
TO_GO_PREV = -1
CODES = { CODES = {
'UNDO':('undo',), 'UNDO':('undo',),
'COMMIT':('commit',), 'COMMIT':('commit',),
'TO GO ALL':('to_go', TO_GO_ALL),
'TO GO NONE':('to_go', TO_GO_NONE),
'TO GO PREV':('to_go', TO_GO_PREV),
'DEPOSIT 0.01':('deposit', Decimal('0.01')), 'DEPOSIT 0.01':('deposit', Decimal('0.01')),
'DEPOSIT 0.05':('deposit', Decimal('0.05')), 'DEPOSIT 0.05':('deposit', Decimal('0.05')),
'DEPOSIT 0.10':('deposit', Decimal('0.10')), 'DEPOSIT 0.10':('deposit', Decimal('0.10')),
@ -87,6 +96,12 @@ class Status:
def color(amount): def color(amount):
return COLOR_WITHDRAW if amount < 0 else COLOR_DEPOSIT return COLOR_WITHDRAW if amount < 0 else COLOR_DEPOSIT
def color_command(command):
diff = command.difference()
if diff >= 0:
return COLOR_DEPOSIT
return COLOR_TO_GO if isinstance(command, ToGoCommand) else COLOR_WITHDRAW
def show_total(balance, plus=' '): def show_total(balance, plus=' '):
print('%3s %-40s %s%c %6.2f Euro%s' \ print('%3s %-40s %s%c %6.2f Euro%s' \
% ('', '', color(balance), sign(balance, plus), % ('', '', color(balance), sign(balance, plus),
@ -96,7 +111,7 @@ class Status:
diff = command.difference() diff = command.difference()
label = command.label() label = command.label()
print('%2d) %-40s %s%c %6.2f Euro%s' \ print('%2d) %-40s %s%c %6.2f Euro%s' \
% (position, label, color(diff), sign(diff), % (position, label, color_command(command), sign(diff),
abs(diff), COLOR_RESET)) abs(diff), COLOR_RESET))
def show_bar(): def show_bar():
@ -190,10 +205,73 @@ class Status:
self.transfers.append(log_entry) self.transfers.append(log_entry)
self.balance = self.balance + amount self.balance = self.balance + amount
def to_go(self, scope):
_PRODUCT_FIRST = 'FEHLER: Bitte zuerst den betreffenden Artikel scannen.'
if not self.transfers:
error_page(_PRODUCT_FIRST)
return
if scope == TO_GO_ALL:
after = list()
dummy, initial_balance = self.transfers[0]
balance_before = initial_balance
def body(prev, command, balance_before):
if isinstance(prev, BuyCommand) \
and prev.deposit() > 0 \
and not isinstance(command, ToGoCommand):
to_go = ToGoCommand(prev)
prev.set_to_go(True)
after.append((to_go, balance_before))
balance_before += to_go.difference()
if command is not None:
after.append((command, balance_before))
balance_before += command.difference()
return balance_before
prev = None
for command, dummy in list(self.transfers):
balance_before = body(prev, command, balance_before)
prev = command
balance_before = body(prev, None, balance_before)
self.balance = balance_before
self.transfers = after
elif scope == TO_GO_NONE:
after = list()
first_command, initial_balance = self.transfers[0]
balance_before = initial_balance
for command, dummy in list(self.transfers):
if isinstance(command, BuyCommand) \
and command.is_to_go():
command.set_to_go(False)
elif isinstance(command, ToGoCommand):
continue
after.append((command, balance_before))
balance_before += command.difference()
self.balance = balance_before
self.transfers = after
elif scope == TO_GO_PREV:
prev, balance_backup = self.transfers[-1]
if not isinstance(prev, BuyCommand):
error_page(_PRODUCT_FIRST)
return
to_go = ToGoCommand(prev)
prev.set_to_go(True)
self.transfers.append((to_go, self.balance))
self.balance += to_go.difference()
def undo(self): def undo(self):
assert(self.logged_in()) assert(self.logged_in())
if self.transfers: if self.transfers:
(command, balance_backup) = self.transfers[-1] (last_command, balance_backup) = self.transfers[-1]
if isinstance(last_command, ToGoCommand) \
and self.transfers:
second_last_command = self.transfers[-2]
if isinstance(second_last_command, BuyCommand):
second_last_command.set_to_go(False)
self.transfers.pop() self.transfers.pop()
self.balance = balance_backup self.balance = balance_backup
else: else:

View File

@ -27,9 +27,31 @@ class BuyCommand(Command):
def __init__(self, item): def __init__(self, item):
self.item = item self.item = item
self._difference = -item.price self._difference = -item.price
self._to_go = False ## TODO session state, instead?
def run(self, user_name): def run(self, user_name):
net.buy_item(self.item.id, user_name) net.buy_item(self.item.id, self._to_go, user_name)
def label(self): def label(self):
return self.item.name return self.item.name
def is_to_go(self):
return self._to_go
def set_to_go(self, to_go):
self._to_go = to_go
def deposit(self):
return self.item.deposit
class ToGoCommand(Command):
def __init__(self, buy_command):
self.buy_command = buy_command
self._difference = -buy_command.item.deposit
def run(self, *args, **kvargs):
pass
def label(self):
return '%s - Pfand' % self.buy_command.label()

View File

@ -51,11 +51,12 @@ def get_user_name_from_auth_blob(authblob):
return d['username'] return d['username']
def buy_item(item_id, user_name): def buy_item(item_id, with_deposit, user_name):
require_type(int, item_id) require_type(int, item_id)
deposit = 0 ## TODO 1 if with_deposit else 0
content = _request('buyable/item/' + urllib.quote(str(item_id)), content = _request('buyable/item/' + urllib.quote(str(item_id)),
{'user':user_name, 'deposit':0, 'amount':1}, method='POST') {'user':user_name, 'deposit':deposit, 'amount':1}, method='POST')
if content != 'Created': if content != 'Created':
raise ValueError('Server says "%s"' % content) raise ValueError('Server says "%s"' % content)
@ -88,7 +89,7 @@ if __name__ == '__main__':
user_name = get_user_name_from_auth_blob(os.environ['BARCODE_PLUGIN_TEST_AUTH_BLOB']) user_name = get_user_name_from_auth_blob(os.environ['BARCODE_PLUGIN_TEST_AUTH_BLOB'])
print('User name: ' + user_name) print('User name: ' + user_name)
buy_item(1, user_name) buy_item(1, True, user_name)
balance = get_balance(user_name) balance = get_balance(user_name)
print('Balance is %f, type is "%s"' % (balance, type(balance).__name__)) print('Balance is %f, type is "%s"' % (balance, type(balance).__name__))