client-barcode: Resolve class ToGoCommand, make UNDO delete commodity/deposity combined
This commit is contained in:
parent
8d6ff280e3
commit
356c2584db
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue