From fafb03c84349676f6c4ab7a4c704d0451c34fdc2 Mon Sep 17 00:00:00 2001 From: Sebastian Pipping Date: Mon, 10 Oct 2011 07:33:13 +0200 Subject: [PATCH] Implement to-go logic for all, none, or previous --- client-barcode/freitagskasse.py | 84 +++++++++++++++++++++++++- client-barcode/freitagslib/commands.py | 24 +++++++- client-barcode/freitagslib/network.py | 7 ++- 3 files changed, 108 insertions(+), 7 deletions(-) diff --git a/client-barcode/freitagskasse.py b/client-barcode/freitagskasse.py index 59304e7..1d56342 100644 --- a/client-barcode/freitagskasse.py +++ b/client-barcode/freitagskasse.py @@ -6,7 +6,7 @@ from __future__ import print_function import freitagslib.network as net -from freitagslib.commands import BuyCommand, DepositCommand +from freitagslib.commands import BuyCommand, DepositCommand, ToGoCommand import colorama from colorama import Fore, Style @@ -22,6 +22,7 @@ import urllib2 COLOR_WARN = Fore.YELLOW COLOR_ERROR = Fore.RED COLOR_DEPOSIT = Fore.GREEN + Style.BRIGHT +COLOR_TO_GO = Fore.MAGENTA + Style.BRIGHT COLOR_WITHDRAW = Fore.RED + Style.BRIGHT COLOR_SOME = Fore.WHITE + Style.BRIGHT @@ -34,10 +35,18 @@ def clear(): os.system('clear') +TO_GO_ALL = 1 +TO_GO_NONE = 0 +TO_GO_PREV = -1 + CODES = { 'UNDO':('undo',), '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.05':('deposit', Decimal('0.05')), 'DEPOSIT 0.10':('deposit', Decimal('0.10')), @@ -87,6 +96,12 @@ class Status: def color(amount): 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=' '): print('%3s %-40s %s%c %6.2f Euro%s' \ % ('', '', color(balance), sign(balance, plus), @@ -96,7 +111,7 @@ class Status: diff = command.difference() label = command.label() 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)) def show_bar(): @@ -190,10 +205,73 @@ class Status: self.transfers.append(log_entry) 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): assert(self.logged_in()) 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.balance = balance_backup else: diff --git a/client-barcode/freitagslib/commands.py b/client-barcode/freitagslib/commands.py index 762d1fc..8fc84fe 100644 --- a/client-barcode/freitagslib/commands.py +++ b/client-barcode/freitagslib/commands.py @@ -27,9 +27,31 @@ class BuyCommand(Command): def __init__(self, item): self.item = item self._difference = -item.price + self._to_go = False ## TODO session state, instead? 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): 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() diff --git a/client-barcode/freitagslib/network.py b/client-barcode/freitagslib/network.py index 60d4109..280ee56 100644 --- a/client-barcode/freitagslib/network.py +++ b/client-barcode/freitagslib/network.py @@ -51,11 +51,12 @@ def get_user_name_from_auth_blob(authblob): return d['username'] -def buy_item(item_id, user_name): +def buy_item(item_id, with_deposit, user_name): require_type(int, item_id) + deposit = 0 ## TODO 1 if with_deposit else 0 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': 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']) print('User name: ' + user_name) - buy_item(1, user_name) + buy_item(1, True, user_name) balance = get_balance(user_name) print('Balance is %f, type is "%s"' % (balance, type(balance).__name__))