client-barcode: Resolve class ToGoCommand, make UNDO delete commodity/deposity combined

master
Sebastian Pipping 13 years ago
parent 8d6ff280e3
commit 356c2584db

@ -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, ToGoCommand from freitagslib.commands import BuyCommand, DepositCommand
import colorama import colorama
from colorama import Fore, Style from colorama import Fore, Style
@ -98,22 +98,14 @@ 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),
abs(balance), COLOR_RESET)) abs(balance), COLOR_RESET))
def show_item(position, command): def show_item(position, diff, label, color):
diff = command.difference()
label = command.label()
print('%2d) %-40s %s%c %6.2f Euro%s' \ print('%2d) %-40s %s%c %6.2f Euro%s' \
% (position, label, color_command(command), sign(diff), % (position, label, color, sign(diff),
abs(diff), COLOR_RESET)) abs(diff), COLOR_RESET))
def show_bar(): def show_bar():
@ -127,8 +119,18 @@ class Status:
print('Geplante Änderungen:') print('Geplante Änderungen:')
show_total(initial_balance) show_total(initial_balance)
for i, (command, balance_backup) in enumerate(self.transfers): i = 1
show_item(i + 1, command) for command, dummy in self.transfers:
if isinstance(command, BuyCommand):
if (command.includes_commodity()):
show_item(i, -command.commodity_value(), command.commodity_label(), COLOR_WITHDRAW)
i += 1
if (command.includes_deposit()):
show_item(i, -command.deposit_value(), command.deposit_label(), COLOR_TO_GO)
i += 1
else:
show_item(i, command.difference(), command.label(), COLOR_DEPOSIT)
i += 1
show_bar() show_bar()
if len(self.transfers) > 1: if len(self.transfers) > 1:
show_total(self.balance - initial_balance, plus='+') show_total(self.balance - initial_balance, plus='+')
@ -215,109 +217,78 @@ class Status:
if scope == TO_GO_ALL: if scope == TO_GO_ALL:
""" """
Adds a ToGoCommands for each BuyCommands with deposit > 0 lacking a pair Makes all BuyCommands with deposit > 0 include deposit
...and updates future balance accordingly.
""" """
after = list()
dummy, initial_balance = self.transfers[0] dummy, initial_balance = self.transfers[0]
balance_before = initial_balance balance_before = initial_balance
def body(prev, command, balance_before): for command, dummy in self.transfers:
if isinstance(prev, BuyCommand) \ if isinstance(command, BuyCommand) \
and prev.deposit() > 0 \ and not command.includes_deposit() \
and (not isinstance(command, ToGoCommand) \ and command.deposit_value() > 0:
or (isinstance(command, ToGoCommand) \ command.include_deposit(True)
and prev.item() != command.item())): balance_before += command.difference()
to_go = ToGoCommand(prev.item())
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.balance = balance_before
self.transfers = after
elif scope == TO_GO_NONE: elif scope == TO_GO_NONE:
""" """
Deletes all ToGoCommands Makes all BuyCommands that include commodity
not include deposit any more
...and updates future balance accordingly.
""" """
after = list()
first_command, initial_balance = self.transfers[0] first_command, initial_balance = self.transfers[0]
balance_before = initial_balance balance_before = initial_balance
for command, dummy in list(self.transfers): for command, dummy in self.transfers:
if isinstance(command, BuyCommand) \ if isinstance(command, BuyCommand) \
and command.is_to_go(): and command.includes_commodity():
command.set_to_go(False) command.include_deposit(False)
elif isinstance(command, ToGoCommand):
continue
after.append((command, balance_before))
balance_before += command.difference() balance_before += command.difference()
self.balance = balance_before self.balance = balance_before
self.transfers = after
elif scope == TO_GO_PREV: elif scope == TO_GO_PREV:
""" """
Adds a ToGoCommand after previous BuyCommand Makes the last BuyCommand include deposit
...and updates future balance accordingly.
""" """
prev, balance_backup = self.transfers[-1] prev, balance_backup = self.transfers[-1]
if not isinstance(prev, BuyCommand): if not isinstance(prev, BuyCommand):
error_page(_PRODUCT_FIRST) error_page(_PRODUCT_FIRST)
return return
to_go = ToGoCommand(prev.item()) if prev.includes_deposit():
prev.set_to_go(True) error_page('FEHLER: Pfand für Produkt "%s" bereits aktiviert' % prev.item_name())
self.transfers.append((to_go, self.balance)) return
self.balance += to_go.difference() if prev.deposit_value() <= 0:
error_page('FEHLER: Produkt "%s" hat kein Pfand' % prev.item_name())
return
before = prev.difference()
prev.include_deposit(True)
after = prev.difference()
self.balance += (after - before)
elif scope == TO_GO_ONLY: elif scope == TO_GO_ONLY:
""" """
Replace all BuyCommands with deposit > 0 by Makes all BuyCommand that include commodity
a ToGoCommand. Resolve ToGoCommand duplicates. be deposit only
...and updates future balance accordingly.
""" """
after = list() dummy, initial_balance = self.transfers[0]
first_command, initial_balance = self.transfers[0]
balance_before = initial_balance balance_before = initial_balance
for command, dummy in list(self.transfers): for command, dummy in self.transfers:
if isinstance(command, ToGoCommand) \ if isinstance(command, BuyCommand) \
and prev_item is not None \ and command.deposit_value() > 0 \
and command.item() == prev_item: and command.includes_commodity():
""" command.include_commodity(False)
Skip this very duplicate command.include_deposit(True)
"""
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() balance_before += command.difference()
self.balance = balance_before self.balance = balance_before
self.transfers = after
def undo(self): def undo(self):
assert(self.logged_in()) assert(self.logged_in())
if self.transfers: if self.transfers:
(last_command, balance_backup) = self.transfers[-1] dummy, 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:

@ -5,18 +5,16 @@
# Licensed under GPL v3 or later # Licensed under GPL v3 or later
import freitagslib.network as net import freitagslib.network as net
from freitagslib.network import ITEM_ONLY, DEPOSIT_ONLY from freitagslib.network import ITEM_ONLY, DEPOSIT_ONLY, ITEM_AND_DEPOSIT
class Command(object): class DepositCommand(object):
def difference(self):
return self._difference
class DepositCommand(Command):
def __init__(self, amount): def __init__(self, amount):
self._difference = amount self._difference = amount
def difference(self):
self._difference
def run(self, user_name): def run(self, user_name):
net.deposit(self._difference, net.DEPOSIT_CASH, user_name) net.deposit(self._difference, net.DEPOSIT_CASH, user_name)
@ -24,43 +22,61 @@ class DepositCommand(Command):
return '%.2f Euro einzahlen' % self._difference return '%.2f Euro einzahlen' % self._difference
class _ItemBasedCommand(Command): class BuyCommand(object):
def __init__(self, item): def __init__(self, item):
self._item = item self._item = item
self._commodity = True
self._deposit = False
def _what_to_buy(self):
if self._deposit and self._commodity:
return ITEM_AND_DEPOSIT
elif self._deposit:
return DEPOSIT_ONLY
elif self._commodity:
return ITEM_ONLY
else:
raise ValueError("BuyCommand in illegal state")
def item(self): def difference(self):
return self._item if self._deposit and self._commodity:
return -(self._item.price + self._item.deposit)
elif self._deposit:
class BuyCommand(_ItemBasedCommand): return -(self._item.deposit)
def __init__(self, item): elif self._commodity:
super(BuyCommand, self).__init__(item) return -(self._item.price)
self._difference = -item.price else:
self._to_go = False ## TODO session state, instead? raise ValueError("BuyCommand in illegal state")
def run(self, user_name): def run(self, user_name):
net.buy_item(self._item.id, what_about_it=ITEM_ONLY, user_name=user_name) net.buy_item(self._item.id, what_about_it=self._what_to_buy(), user_name=user_name)
def label(self): def item_name(self):
return self._item.name return self._item.name
def is_to_go(self): def commodity_label(self):
return self._to_go if self._deposit:
return self._item.name
else:
return "%s (exkl. Pfand)" % self._item.name
def set_to_go(self, to_go): def deposit_label(self):
self._to_go = to_go return '%s Pfand' % self._item.name
def deposit(self): def includes_commodity(self):
return self._item.deposit return self._commodity
def includes_deposit(self):
return self._deposit
class ToGoCommand(_ItemBasedCommand): def include_commodity(self, commodity):
def __init__(self, item): self._commodity = commodity
super(ToGoCommand, self).__init__(item)
self._difference = -item.deposit
def run(self, user_name): def include_deposit(self, deposit):
net.buy_item(self._item.id, what_about_it=DEPOSIT_ONLY, user_name=user_name) self._deposit = deposit
def label(self): def commodity_value(self):
return '%s Pfand' % self._item.name return self._item.price
def deposit_value(self):
return self._item.deposit

Loading…
Cancel
Save