2017-02-20 13:19:03 +01:00
|
|
|
from math import ceil
|
|
|
|
|
|
|
|
import sqlalchemy
|
2017-02-21 16:38:41 +01:00
|
|
|
from db import Product, User, Transaction, PurchaseEntry, Purchase
|
2017-02-20 13:19:03 +01:00
|
|
|
from text_interface.helpermenus import Menu
|
|
|
|
|
|
|
|
|
|
|
|
class AddStockMenu(Menu):
|
|
|
|
def __init__(self):
|
|
|
|
Menu.__init__(self, 'Add stock and adjust credit', uses_db=True)
|
|
|
|
self.help_text = '''
|
|
|
|
Enter what you have bought for PVVVV here, along with your user name and how
|
|
|
|
much money you're due in credits for the purchase when prompted.\n'''
|
2017-02-25 17:28:38 +01:00
|
|
|
self.users = []
|
|
|
|
self.users = []
|
|
|
|
self.products = {}
|
|
|
|
self.price = 0
|
2017-02-20 13:19:03 +01:00
|
|
|
|
|
|
|
def _execute(self):
|
|
|
|
questions = {
|
|
|
|
(False, False): 'Enter user id or a string of the form "<number> <product>"',
|
|
|
|
(False, True): 'Enter user id or more strings of the form "<number> <product>"',
|
|
|
|
(True, False): 'Enter a string of the form "<number> <product>"',
|
|
|
|
(True, True): 'Enter more strings of the form "<number> <product>", or an empty line to confirm'
|
|
|
|
}
|
|
|
|
|
2017-02-25 17:28:38 +01:00
|
|
|
self.users = []
|
2017-02-20 13:19:03 +01:00
|
|
|
self.products = {}
|
|
|
|
self.price = 0
|
|
|
|
|
|
|
|
while True:
|
|
|
|
self.print_info()
|
2017-02-25 17:28:38 +01:00
|
|
|
self.printc(questions[bool(self.users), bool(len(self.products))])
|
2017-02-20 13:19:03 +01:00
|
|
|
thing_price = 0
|
|
|
|
|
|
|
|
# Read in a 'thing' (product or user):
|
|
|
|
line = self.input_multiple(add_nonexisting=('user', 'product'), empty_input_permitted=True,
|
|
|
|
find_hidden_products=False)
|
|
|
|
|
|
|
|
if line:
|
|
|
|
(thing, amount) = line
|
|
|
|
|
|
|
|
if isinstance(thing, Product):
|
2018-08-23 13:15:45 +02:00
|
|
|
self.printc(f"{amount:d} of {thing.name} registered")
|
2019-09-21 16:48:49 +02:00
|
|
|
thing_price = self.input_int('What did you pay a piece?', 1, 100000, default=thing.price) * amount
|
2017-02-20 13:19:03 +01:00
|
|
|
self.price += thing_price
|
|
|
|
|
|
|
|
# once we get something in the
|
|
|
|
# purchase, we want to protect the
|
|
|
|
# user from accidentally killing it
|
|
|
|
self.exit_confirm_msg = 'Abort transaction?'
|
|
|
|
else:
|
|
|
|
if not self.complete_input():
|
|
|
|
if self.confirm('Not enough information entered. Abort transaction?', default=True):
|
|
|
|
return False
|
|
|
|
continue
|
|
|
|
break
|
|
|
|
|
|
|
|
# Add the thing to the pending adjustments:
|
|
|
|
self.add_thing_to_pending(thing, amount, thing_price)
|
|
|
|
|
|
|
|
self.perform_transaction()
|
|
|
|
|
|
|
|
def complete_input(self):
|
2017-02-25 17:28:38 +01:00
|
|
|
return bool(self.users) and len(self.products) and self.price
|
2017-02-20 13:19:03 +01:00
|
|
|
|
|
|
|
def print_info(self):
|
2019-09-21 16:48:49 +02:00
|
|
|
width = 6 + Product.name_length
|
|
|
|
print()
|
|
|
|
print(width * '-')
|
2017-02-20 13:19:03 +01:00
|
|
|
if self.price:
|
2019-09-21 16:48:49 +02:00
|
|
|
print(f"Amount to be credited:{self.price:>{width - 22}}")
|
2017-02-25 17:28:38 +01:00
|
|
|
if self.users:
|
2018-08-19 16:38:45 +02:00
|
|
|
print("Users to credit:")
|
2017-02-25 17:28:38 +01:00
|
|
|
for user in self.users:
|
2019-09-21 16:48:49 +02:00
|
|
|
print(f"\t{user.name}")
|
|
|
|
print()
|
|
|
|
print("Products", end="")
|
|
|
|
print("Amount".rjust(width - 8))
|
|
|
|
print(width * '-')
|
2017-02-20 13:19:03 +01:00
|
|
|
if len(self.products):
|
2018-08-19 16:38:45 +02:00
|
|
|
for product in list(self.products.keys()):
|
2019-09-21 16:48:49 +02:00
|
|
|
print(f"{product.name}", end="")
|
|
|
|
print(f"{self.products[product][0]}".rjust(width - len(product.name)))
|
|
|
|
print(width * '-')
|
2017-02-20 13:19:03 +01:00
|
|
|
|
|
|
|
def add_thing_to_pending(self, thing, amount, price):
|
|
|
|
if isinstance(thing, User):
|
2017-02-25 17:28:38 +01:00
|
|
|
self.users.append(thing)
|
2018-08-19 16:38:45 +02:00
|
|
|
elif thing in list(self.products.keys()):
|
|
|
|
print('Already added this product, adding amounts')
|
2017-02-20 13:19:03 +01:00
|
|
|
self.products[thing][0] += amount
|
|
|
|
self.products[thing][1] += price
|
|
|
|
else:
|
|
|
|
self.products[thing] = [amount, price]
|
|
|
|
|
|
|
|
def perform_transaction(self):
|
2018-08-19 16:38:45 +02:00
|
|
|
print('Did you pay a different price?')
|
2018-04-22 17:44:24 +02:00
|
|
|
if self.confirm('>', default=False):
|
2019-09-21 16:48:49 +02:00
|
|
|
self.price = self.input_int('How much did you pay?', 0, self.price, default=self.price)
|
2017-05-12 21:34:33 +02:00
|
|
|
|
2018-08-30 14:59:37 +02:00
|
|
|
description = self.input_str('Log message', length_range=(0, 50))
|
2017-02-20 13:19:03 +01:00
|
|
|
if description == '':
|
|
|
|
description = 'Purchased products for PVVVV, adjusted credit ' + str(self.price)
|
|
|
|
for product in self.products:
|
|
|
|
value = max(product.stock, 0) * product.price + self.products[product][1]
|
|
|
|
old_price = product.price
|
|
|
|
old_hidden = product.hidden
|
|
|
|
product.price = int(ceil(float(value) / (max(product.stock, 0) + self.products[product][0])))
|
2017-06-11 16:25:27 +02:00
|
|
|
product.stock = max(self.products[product][0], product.stock + self.products[product][0])
|
2017-02-20 13:19:03 +01:00
|
|
|
product.hidden = False
|
2018-08-23 13:15:45 +02:00
|
|
|
print(f"New stock for {product.name}: {product.stock:d}",
|
|
|
|
f"- New price: {product.price}" if old_price != product.price else "",
|
|
|
|
"- Removed hidden status" if old_hidden != product.hidden else "")
|
2017-02-21 16:38:41 +01:00
|
|
|
|
|
|
|
purchase = Purchase()
|
2017-02-25 17:28:38 +01:00
|
|
|
for user in self.users:
|
|
|
|
Transaction(user, purchase=purchase, amount=-self.price, description=description)
|
2017-02-21 16:38:41 +01:00
|
|
|
for product in self.products:
|
|
|
|
PurchaseEntry(purchase, product, -self.products[product][0])
|
|
|
|
|
|
|
|
purchase.perform_soft_purchase(-self.price, round_up=False)
|
|
|
|
self.session.add(purchase)
|
|
|
|
|
2017-02-20 13:19:03 +01:00
|
|
|
try:
|
|
|
|
self.session.commit()
|
2018-08-19 16:38:45 +02:00
|
|
|
print("Success! Transaction performed:")
|
2017-02-20 13:19:03 +01:00
|
|
|
# self.print_info()
|
2017-02-25 17:28:38 +01:00
|
|
|
for user in self.users:
|
2018-08-23 13:15:45 +02:00
|
|
|
print(f"User {user.name}'s credit is now {user.credit:d}")
|
2018-08-19 16:38:45 +02:00
|
|
|
except sqlalchemy.exc.SQLAlchemyError as e:
|
2018-08-23 13:15:45 +02:00
|
|
|
print(f'Could not perform transaction: {e}')
|