From f697486296c146c146297823210bbd6a05ac703e Mon Sep 17 00:00:00 2001 From: Sebastian Pipping Date: Mon, 10 Oct 2011 21:58:35 +0200 Subject: [PATCH] client-barcode: Allow buying sole deposit of an item --- client-barcode/freitagskasse.py | 52 ++++++++++++++++++++++++-- client-barcode/freitagslib/commands.py | 33 ++++++++++------ client-barcode/freitagslib/network.py | 8 ++-- 3 files changed, 75 insertions(+), 18 deletions(-) diff --git a/client-barcode/freitagskasse.py b/client-barcode/freitagskasse.py index 25c8155..17a3b84 100644 --- a/client-barcode/freitagskasse.py +++ b/client-barcode/freitagskasse.py @@ -35,6 +35,7 @@ def clear(): os.system('clear') +TO_GO_ONLY = 2 TO_GO_ALL = 1 TO_GO_NONE = 0 TO_GO_PREV = -1 @@ -46,6 +47,7 @@ CODES = { 'TO GO ALL':('to_go', TO_GO_ALL), 'TO GO NONE':('to_go', TO_GO_NONE), 'TO GO PREV':('to_go', TO_GO_PREV), + 'TO GO ONLY':('to_go', TO_GO_ONLY), 'DEPOSIT 0.01':('deposit', Decimal('0.01')), 'DEPOSIT 0.05':('deposit', Decimal('0.05')), @@ -212,6 +214,9 @@ class Status: return if scope == TO_GO_ALL: + """ + Adds a ToGoCommands for each BuyCommands with deposit > 0 lacking a pair + """ after = list() dummy, initial_balance = self.transfers[0] balance_before = initial_balance @@ -219,8 +224,10 @@ class Status: def body(prev, command, balance_before): if isinstance(prev, BuyCommand) \ and prev.deposit() > 0 \ - and not isinstance(command, ToGoCommand): - to_go = ToGoCommand(prev) + and (not isinstance(command, ToGoCommand) \ + or (isinstance(command, ToGoCommand) \ + and prev.item() != command.item())): + to_go = ToGoCommand(prev.item()) prev.set_to_go(True) after.append((to_go, balance_before)) balance_before += to_go.difference() @@ -238,6 +245,9 @@ class Status: self.balance = balance_before self.transfers = after elif scope == TO_GO_NONE: + """ + Deletes all ToGoCommands + """ after = list() first_command, initial_balance = self.transfers[0] balance_before = initial_balance @@ -254,14 +264,50 @@ class Status: self.balance = balance_before self.transfers = after elif scope == TO_GO_PREV: + """ + Adds a ToGoCommand after previous BuyCommand + """ prev, balance_backup = self.transfers[-1] if not isinstance(prev, BuyCommand): error_page(_PRODUCT_FIRST) return - to_go = ToGoCommand(prev) + to_go = ToGoCommand(prev.item()) prev.set_to_go(True) self.transfers.append((to_go, self.balance)) self.balance += to_go.difference() + elif scope == TO_GO_ONLY: + """ + Replace all BuyCommands with deposit > 0 by + a ToGoCommand. Resolve ToGoCommand duplicates. + """ + after = list() + first_command, initial_balance = self.transfers[0] + balance_before = initial_balance + + for command, dummy in list(self.transfers): + if isinstance(command, ToGoCommand) \ + and prev_item is not None \ + and command.item() == prev_item: + """ + Skip this very duplicate + """ + prev_item = None + continue + elif isinstance(command, BuyCommand) \ + and command.deposit() > 0: + """ + Replace by ToGoCommand + """ + item = command.item() + command = ToGoCommand(item) + prev_item = item + else: + prev_item = None + after.append((command, balance_before)) + balance_before += command.difference() + + self.balance = balance_before + self.transfers = after def undo(self): assert(self.logged_in()) diff --git a/client-barcode/freitagslib/commands.py b/client-barcode/freitagslib/commands.py index 8fc84fe..a38cfcd 100644 --- a/client-barcode/freitagslib/commands.py +++ b/client-barcode/freitagslib/commands.py @@ -5,6 +5,7 @@ # Licensed under GPL v3 or later import freitagslib.network as net +from freitagslib.network import ITEM_ONLY, DEPOSIT_ONLY class Command(object): @@ -23,17 +24,25 @@ class DepositCommand(Command): return '%.2f Euro einzahlen' % self._difference -class BuyCommand(Command): +class _ItemBasedCommand(Command): def __init__(self, item): - self.item = item + self._item = item + + def item(self): + return self._item + + +class BuyCommand(_ItemBasedCommand): + def __init__(self, item): + super(BuyCommand, self).__init__(item) self._difference = -item.price self._to_go = False ## TODO session state, instead? def run(self, user_name): - net.buy_item(self.item.id, self._to_go, user_name) + net.buy_item(self._item.id, what_about_it=ITEM_ONLY, user_name=user_name) def label(self): - return self.item.name + return self._item.name def is_to_go(self): return self._to_go @@ -42,16 +51,16 @@ class BuyCommand(Command): self._to_go = to_go def deposit(self): - return self.item.deposit + return self._item.deposit -class ToGoCommand(Command): - def __init__(self, buy_command): - self.buy_command = buy_command - self._difference = -buy_command.item.deposit +class ToGoCommand(_ItemBasedCommand): + def __init__(self, item): + super(ToGoCommand, self).__init__(item) + self._difference = -item.deposit - def run(self, *args, **kvargs): - pass + def run(self, user_name): + net.buy_item(self._item.id, what_about_it=DEPOSIT_ONLY, user_name=user_name) def label(self): - return '%s - Pfand' % self.buy_command.label() + return '%s - Pfand' % self._item.name diff --git a/client-barcode/freitagslib/network.py b/client-barcode/freitagslib/network.py index fad5a0f..5b75030 100644 --- a/client-barcode/freitagslib/network.py +++ b/client-barcode/freitagslib/network.py @@ -28,6 +28,8 @@ _BASE_URL = 'http://devcat.someserver.de:13805/api2/' _auth = base64.encodestring('%s:%s' % (os.environ['BARCODE_PLUGIN_USER'], os.environ['BARCODE_PLUGIN_PASS'])).rstrip() _headers = {'Authorization':'Basic %s' % _auth} +ITEM_ONLY, DEPOSIT_ONLY, ITEM_AND_DEPOSIT = range(3) + def _request(api_rel_url, para_map, method): url = _BASE_URL + api_rel_url @@ -51,12 +53,12 @@ def get_user_name_from_auth_blob(authblob): return d['username'] -def buy_item(item_id, with_deposit, user_name): +def buy_item(item_id, what_about_it, user_name): require_type(int, item_id) + assert(what_about_it in (ITEM_ONLY, DEPOSIT_ONLY, ITEM_AND_DEPOSIT)) - deposit = 1 if with_deposit else 0 content = _request('buyable/item/' + urllib.quote(str(item_id)), - {'user':user_name, 'deposit':deposit, 'amount':1}, method='POST') + {'user':user_name, 'deposit':what_about_it, 'amount':1}, method='POST') if content != 'Created': raise ValueError('Server says "%s"' % content)