Implement to-go logic for all, none, or previous
This commit is contained in:
		
							parent
							
								
									cf5cae5303
								
							
						
					
					
						commit
						fafb03c843
					
				|  | @ -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: | ||||
|  |  | |||
|  | @ -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() | ||||
|  |  | |||
|  | @ -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__)) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Sebastian Pipping
						Sebastian Pipping