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

This commit is contained in:
Sebastian Pipping 2011-10-12 05:51:04 +02:00
parent 8d6ff280e3
commit 356c2584db
2 changed files with 112 additions and 125 deletions

View File

@ -6,7 +6,7 @@
from __future__ import print_function
import freitagslib.network as net
from freitagslib.commands import BuyCommand, DepositCommand, ToGoCommand
from freitagslib.commands import BuyCommand, DepositCommand
import colorama
from colorama import Fore, Style
@ -98,22 +98,14 @@ 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),
abs(balance), COLOR_RESET))
def show_item(position, command):
diff = command.difference()
label = command.label()
def show_item(position, diff, label, color):
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))
def show_bar():
@ -127,8 +119,18 @@ class Status:
print('Geplante Änderungen:')
show_total(initial_balance)
for i, (command, balance_backup) in enumerate(self.transfers):
show_item(i + 1, command)
i = 1
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()
if len(self.transfers) > 1:
show_total(self.balance - initial_balance, plus='+')
@ -215,109 +217,78 @@ class Status:
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]
balance_before = initial_balance
def body(prev, command, balance_before):
if isinstance(prev, BuyCommand) \
and prev.deposit() > 0 \
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()
if command is not None:
after.append((command, balance_before))
for command, dummy in self.transfers:
if isinstance(command, BuyCommand) \
and not command.includes_deposit() \
and command.deposit_value() > 0:
command.include_deposit(True)
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:
"""
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]
balance_before = initial_balance
for command, dummy in list(self.transfers):
for command, dummy in 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))
and command.includes_commodity():
command.include_deposit(False)
balance_before += command.difference()
self.balance = balance_before
self.transfers = after
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]
if not isinstance(prev, BuyCommand):
error_page(_PRODUCT_FIRST)
return
to_go = ToGoCommand(prev.item())
prev.set_to_go(True)
self.transfers.append((to_go, self.balance))
self.balance += to_go.difference()
if prev.includes_deposit():
error_page('FEHLER: Pfand für Produkt "%s" bereits aktiviert' % prev.item_name())
return
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:
"""
Replace all BuyCommands with deposit > 0 by
a ToGoCommand. Resolve ToGoCommand duplicates.
Makes all BuyCommand that include commodity
be deposit only
...and updates future balance accordingly.
"""
after = list()
first_command, initial_balance = self.transfers[0]
dummy, 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))
for command, dummy in self.transfers:
if isinstance(command, BuyCommand) \
and command.deposit_value() > 0 \
and command.includes_commodity():
command.include_commodity(False)
command.include_deposit(True)
balance_before += command.difference()
self.balance = balance_before
self.transfers = after
def undo(self):
assert(self.logged_in())
if self.transfers:
(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)
dummy, balance_backup = self.transfers[-1]
self.transfers.pop()
self.balance = balance_backup
else:

View File

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