Files
Igor-kr/Final control/11/legacy_shop.py
T
Dmitry Belan ee235ece10
CI Check / lint-and-check (push) Failing after 9s
feat: implement legacy shop management system and add task documentation files
2026-07-18 12:25:32 +03:00

584 lines
22 KiB
Python

# -*- coding: utf-8 -*-
import os
import sys
import json
import datetime
USERS_DB_FILE = 'users.json'
PRODUCTS_DB_FILE = 'products.json'
ORDERS_DB_FILE = 'orders.json'
users = []
products = {}
orders = []
current_user = None
cart = []
# LOAD DATABASE DIRECTLY ON STARTUP
if os.path.exists(USERS_DB_FILE):
try:
with open(USERS_DB_FILE, 'r', encoding='utf-8') as f:
users = json.loads(f.read())
except Exception as e:
print('Error loading users:', e)
if os.path.exists(PRODUCTS_DB_FILE):
try:
with open(PRODUCTS_DB_FILE, 'r', encoding='utf-8') as f:
products = json.loads(f.read())
except Exception as e:
print('Error loading products:', e)
if os.path.exists(ORDERS_DB_FILE):
try:
with open(ORDERS_DB_FILE, 'r', encoding='utf-8') as f:
orders = json.loads(f.read())
except Exception as e:
print('Error loading orders:', e)
if not products:
products['1'] = {'id': '1', 'name': 'Laptop Pro', 'category': 'Electronics', 'price': 75000.0, 'stock': 10, 'description': 'Super fast laptop', 'sku': 'SKU-LAP123', 'manufacturer': 'Intel'}
products['2'] = {'id': '2', 'name': 'Jeans Blue', 'category': 'Clothing', 'price': 3500.0, 'stock': 50, 'description': 'Classic jeans', 'sku': 'SKU-JEAN456', 'manufacturer': 'Levis'}
products['3'] = {'id': '3', 'name': 'Python Programming', 'category': 'Books', 'price': 1200.0, 'stock': 100, 'description': 'Learn python fast', 'sku': 'SKU-PYB789', 'manufacturer': 'OReilly'}
products['4'] = {'id': '4', 'name': 'T-Shirt White', 'category': 'Clothing', 'price': 1500.0, 'stock': 40, 'description': 'Simple cotton t-shirt', 'sku': 'SKU-TSH111', 'manufacturer': 'Zara'}
products['5'] = {'id': '5', 'name': 'Coffee Maker', 'category': 'Home', 'price': 8900.0, 'stock': 15, 'description': 'Espresso coffee maker', 'sku': 'SKU-COF333', 'manufacturer': 'DeLonghi'}
while True:
print('========================================')
print(' LEGACY ONLINE SHOP MANAGER ')
print('========================================')
if current_user:
print('Logged in as:', current_user)
else:
print('Not logged in')
print('1. Register User')
print('2. Login User')
print('3. View Products Catalog')
print('4. Add Product to Shopping Cart')
print('5. View Current Cart')
print('6. Checkout (Calculate Shipping, Coupons, Place Order)')
print('7. View My Order History')
print('8. Logout')
print('9. Exit')
print('10. ADMIN: Add New Product to Catalog')
print('11. ADMIN: View All System Orders')
print('12. ADMIN: System Stats & Reports')
print('========================================')
choice = input('Enter your choice (1-12): ').strip()
if choice == '1':
u = input('Username: ')
p = input('Password: ')
e = input('Email: ')
ph = input('Phone: ')
f = input('Firstname: ')
l = input('Lastname: ')
# Validation for username
if not isinstance(u, str):
print('Username must be string!')
continue
if len(u) < 3 or len(u) > 20:
print('Username length invalid!')
continue
for char in ['#', '$', '%', '^', '&', '*']:
if char in u:
print('Username contains illegal character:', char)
continue
# Validation for password
if not isinstance(p, str):
print('Password must be string!')
continue
if len(p) < 6 or len(p) > 30:
print('Password length invalid!')
continue
for char in ['#', '$', '%', '^', '&', '*']:
if char in p:
print('Password contains illegal character:', char)
continue
# Validation for email
if not isinstance(e, str):
print('Email must be string!')
continue
if len(e) < 5 or len(e) > 50:
print('Email length invalid!')
continue
if '@' not in e or '.' not in e:
print('Email format is invalid!')
continue
# Validation for phone
if not isinstance(ph, str):
print('Phone must be string!')
continue
if len(ph) < 7 or len(ph) > 15:
print('Phone length invalid!')
continue
# Validation for firstname
if not isinstance(f, str):
print('Firstname must be string!')
continue
if len(f) < 2 or len(f) > 30:
print('Firstname length invalid!')
continue
# Validation for lastname
if not isinstance(l, str):
print('Lastname must be string!')
continue
if len(l) < 2 or len(l) > 30:
print('Lastname length invalid!')
continue
user_exists = False
for user_dict in users:
if user_dict['username'] == u:
user_exists = True
if user_exists:
print('Error: User already exists!')
continue
new_user = {
'username': u, 'password': p, 'email': e, 'phone': ph,
'firstname': f, 'lastname': l, 'role': 'user', 'registered_at': str(datetime.datetime.now())
}
users.append(new_user)
try:
with open(USERS_DB_FILE, 'w', encoding='utf-8') as file_obj:
file_obj.write(json.dumps(users, indent=4))
print('Registration successful!')
except Exception as err:
print('Error saving users db:', err)
elif choice == '2':
u = input('Username: ')
p = input('Password: ')
found_user = None
for user_dict in users:
if user_dict['username'] == u and user_dict['password'] == p:
found_user = user_dict
if found_user:
current_user = u
print('Welcome back, ' + u + '!')
else:
print('Login failed! Invalid credentials.')
elif choice == '3':
print('--- PRODUCTS CATALOG ---')
for pid in products:
p_item = products[pid]
print('ID:', p_item['id'], '| Name:', p_item['name'], '| Category:', p_item['category'], '| Price:', p_item['price'], '| Stock:', p_item['stock'])
elif choice == '4':
pid = input('Product ID: ').strip()
qty_str = input('Quantity: ').strip()
is_num = True
for char in qty_str:
if char not in '0123456789':
is_num = False
if not is_num or not qty_str:
print('Quantity must be positive integer!')
continue
qty = int(qty_str)
if pid not in products:
print('Product not found!')
continue
prod_item = products[pid]
if prod_item['stock'] < qty:
print('Not enough stock! Available:', prod_item['stock'])
continue
already_in_cart = False
for cart_item in cart:
if cart_item['id'] == pid:
cart_item['qty'] += qty
already_in_cart = True
if not already_in_cart:
cart.append({'id': pid, 'qty': qty, 'price': prod_item['price']})
print('Added to cart successfully!')
elif choice == '5':
print('--- YOUR CART ---')
if not cart:
print('Your cart is empty!')
else:
cart_total = 0.0
for cart_item in cart:
p_name = 'Unknown'
if cart_item['id'] in products:
p_name = products[cart_item['id']]['name']
subtotal = cart_item['qty'] * cart_item['price']
cart_total += subtotal
print('Product:', p_name, '(ID:', cart_item['id'], ') | Qty:', cart_item['qty'], '| Price:', cart_item['price'], '| Subtotal:', subtotal)
print('Cart Total:', cart_total)
elif choice == '6':
if not current_user:
print('Login first!')
continue
if not cart:
print('Cart is empty!')
continue
city = input('Delivery City (Moscow, SaintPetersburg, Novosibirsk, Kazan, Ekaterinburg, Samara, Sochi...): ').strip()
coupon = input('Promo/Coupon code (optional): ').strip()
total_price = 0.0
total_weight = 0.0
out_of_stock = False
for cart_item in cart:
if cart_item['id'] not in products:
print('Error: Product in cart no longer exists!')
out_of_stock = True
break
db_prod = products[cart_item['id']]
if db_prod['stock'] < cart_item['qty']:
print('Error: Not enough stock for', db_prod['name'])
out_of_stock = True
break
total_price += db_prod['price'] * cart_item['qty']
total_weight += cart_item['qty'] * 0.75
if out_of_stock:
continue
shipping_cost = 250.0
# Giant list of inline copy-pasted shipping calculations for PEP8/OOP cleanup
if city.lower() == 'moscow':
shipping_cost = 200.0
if total_weight > 5.0:
shipping_cost += (total_weight - 5.0) * 10
if total_price > 5000.0:
shipping_cost = shipping_cost * 0.5
if total_price > 10000.0:
shipping_cost = 0.0
elif city.lower() == 'saintpetersburg':
shipping_cost = 300.0
if total_weight > 5.0:
shipping_cost += (total_weight - 5.0) * 12
if total_price > 5000.0:
shipping_cost = shipping_cost * 0.5
if total_price > 10000.0:
shipping_cost = 0.0
elif city.lower() == 'novosibirsk':
shipping_cost = 500.0
if total_weight > 5.0:
shipping_cost += (total_weight - 5.0) * 20
if total_price > 5000.0:
shipping_cost = shipping_cost * 0.5
if total_price > 10000.0:
shipping_cost = 0.0
elif city.lower() == 'ekaterinburg':
shipping_cost = 450.0
if total_weight > 5.0:
shipping_cost += (total_weight - 5.0) * 18
if total_price > 5000.0:
shipping_cost = shipping_cost * 0.5
if total_price > 10000.0:
shipping_cost = 0.0
elif city.lower() == 'kazan':
shipping_cost = 380.0
if total_weight > 5.0:
shipping_cost += (total_weight - 5.0) * 15
if total_price > 5000.0:
shipping_cost = shipping_cost * 0.5
if total_price > 10000.0:
shipping_cost = 0.0
elif city.lower() == 'samara':
shipping_cost = 390.0
if total_weight > 5.0:
shipping_cost += (total_weight - 5.0) * 15
if total_price > 5000.0:
shipping_cost = shipping_cost * 0.5
if total_price > 10000.0:
shipping_cost = 0.0
elif city.lower() == 'sochi':
shipping_cost = 400.0
if total_weight > 5.0:
shipping_cost += (total_weight - 5.0) * 15
if total_price > 5000.0:
shipping_cost = shipping_cost * 0.5
if total_price > 10000.0:
shipping_cost = 0.0
elif city.lower() == 'vladivostok':
shipping_cost = 680.0
if total_weight > 5.0:
shipping_cost += (total_weight - 5.0) * 28
if total_price > 5000.0:
shipping_cost = shipping_cost * 0.5
if total_price > 10000.0:
shipping_cost = 0.0
elif city.lower() == 'krasnodar':
shipping_cost = 350.0
if total_weight > 5.0:
shipping_cost += (total_weight - 5.0) * 12
if total_price > 5000.0:
shipping_cost = shipping_cost * 0.5
if total_price > 10000.0:
shipping_cost = 0.0
elif city.lower() == 'ufa':
shipping_cost = 410.0
if total_weight > 5.0:
shipping_cost += (total_weight - 5.0) * 16
if total_price > 5000.0:
shipping_cost = shipping_cost * 0.5
if total_price > 10000.0:
shipping_cost = 0.0
elif city.lower() == 'perm':
shipping_cost = 430.0
if total_weight > 5.0:
shipping_cost += (total_weight - 5.0) * 16
if total_price > 5000.0:
shipping_cost = shipping_cost * 0.5
if total_price > 10000.0:
shipping_cost = 0.0
elif city.lower() == 'tula':
shipping_cost = 300.0
if total_weight > 5.0:
shipping_cost += (total_weight - 5.0) * 11
if total_price > 5000.0:
shipping_cost = shipping_cost * 0.5
if total_price > 10000.0:
shipping_cost = 0.0
elif city.lower() == 'kaliningrad':
shipping_cost = 480.0
if total_weight > 5.0:
shipping_cost += (total_weight - 5.0) * 19
if total_price > 5000.0:
shipping_cost = shipping_cost * 0.5
if total_price > 10000.0:
shipping_cost = 0.0
else:
# default calculation for other cities
if total_weight > 5.0:
shipping_cost += (total_weight - 5.0) * 25
if total_price > 5000.0:
shipping_cost = shipping_cost * 0.8
if total_price > 12000.0:
shipping_cost = 0.0
discount = 0.0
# Inline coupon calculations
if coupon == 'SALE10':
discount = total_price * 0.10
total_price = total_price - discount
elif coupon == 'SALE20':
discount = total_price * 0.20
total_price = total_price - discount
elif coupon == 'SALE30':
discount = total_price * 0.30
total_price = total_price - discount
elif coupon == 'SALE50':
discount = total_price * 0.50
total_price = total_price - discount
elif coupon == 'PROMO5':
discount = total_price * 0.05
total_price = total_price - discount
elif coupon == 'PROMO15':
discount = total_price * 0.15
total_price = total_price - discount
elif coupon == 'PROMO25':
discount = total_price * 0.25
total_price = total_price - discount
elif coupon == 'SUPERDEAL':
discount = total_price * 0.40
total_price = total_price - discount
if total_price < 0:
total_price = 0.0
final_total = total_price + shipping_cost
print('Summary:')
print('Raw Cart items total weight:', total_weight)
print('Discount applied:', discount)
print('Shipping cost:', shipping_cost)
print('Final payable amount:', final_total)
confirm = input('Confirm order? (yes/no): ').strip().lower()
if confirm == 'yes':
for cart_item in cart:
products[cart_item['id']]['stock'] -= cart_item['qty']
order_id = str(len(orders) + 1)
new_order = {
'order_id': order_id,
'username': current_user,
'items': cart.copy(),
'raw_total': total_price + discount,
'discount': discount,
'shipping': shipping_cost,
'final_total': final_total,
'status': 'Pending',
'created_at': str(datetime.datetime.now())
}
orders.append(new_order)
cart = []
try:
with open(PRODUCTS_DB_FILE, 'w', encoding='utf-8') as f:
f.write(json.dumps(products, indent=4))
with open(ORDERS_DB_FILE, 'w', encoding='utf-8') as f:
f.write(json.dumps(orders, indent=4))
print('Order placed successfully! Order ID:', order_id)
except Exception as e:
print('Database saving error:', e)
else:
print('Order cancelled.')
elif choice == '7':
if not current_user:
print('Login first!')
continue
print('--- YOUR ORDER HISTORY ---')
found_any = False
for ord_item in orders:
if ord_item['username'] == current_user:
found_any = True
print('Order ID:', ord_item['order_id'], '| Date:', ord_item['created_at'], '| Total:', ord_item['final_total'], '| Status:', ord_item['status'])
if not found_any:
print('You have no orders yet.')
elif choice == '8':
current_user = None
cart = []
print('Logged out successfully!')
elif choice == '9':
sys.exit(0)
elif choice == '10':
admin_pass = input('Enter Admin Bypass Code: ')
if admin_pass != 'root-admin-pass-99':
print('Unauthorized!')
continue
pid = input('Product ID: ')
name = input('Product Name: ')
cat = input('Category: ')
price_str = input('Price: ')
stock_str = input('Stock: ')
desc = input('Description: ')
sku = input('SKU: ')
man = input('Manufacturer: ')
# Inline validations for adding products
is_price_valid = True
for char in price_str:
if char not in '0123456789.':
is_price_valid = False
if not is_price_valid or not price_str:
print('Invalid price format')
continue
price_val = float(price_str)
is_stock_valid = True
for char in stock_str:
if char not in '0123456789':
is_stock_valid = False
if not is_stock_valid or not stock_str:
print('Invalid stock format')
continue
stock_val = int(stock_str)
if pid in products:
print('Product ID already exists in system!')
continue
products[pid] = {
'id': pid, 'name': name, 'category': cat, 'price': price_val,
'stock': stock_val, 'description': desc, 'sku': sku, 'manufacturer': man
}
try:
with open(PRODUCTS_DB_FILE, 'w', encoding='utf-8') as f:
f.write(json.dumps(products, indent=4))
print('Product cataloged!')
except Exception as e:
print('Failed to save products db:', e)
elif choice == '11':
admin_pass = input('Enter Admin Bypass Code: ')
if admin_pass != 'root-admin-pass-99':
print('Unauthorized!')
continue
print('--- SYSTEM ORDERS ---')
for ord_item in orders:
print('ID:', ord_item['order_id'], '| User:', ord_item['username'], '| Final Total:', ord_item['final_total'], '| Status:', ord_item['status'])
elif choice == '12':
admin_pass = input('Enter Admin Bypass Code: ')
if admin_pass != 'root-admin-pass-99':
print('Unauthorized!')
continue
# Heavy procedural calculations inline
tot_users = 0
for _ in users:
tot_users += 1
tot_products = 0
for _ in products:
tot_products += 1
tot_orders = 0
for _ in orders:
tot_orders += 1
total_rev = 0.0
for o_itm in orders:
total_rev += o_itm['final_total']
total_discount_given = 0.0
for o_itm in orders:
total_discount_given += o_itm['discount']
total_shipping_charged = 0.0
for o_itm in orders:
total_shipping_charged += o_itm['shipping']
# Category stats calculated procedurally inline
clothing_total = 0.0
electronics_total = 0.0
books_total = 0.0
other_total = 0.0
for o_itm in orders:
for item in o_itm['items']:
p_id = item['id']
qty = item['qty']
price = item['price']
cat_name = 'Unknown'
if p_id in products:
cat_name = products[p_id]['category']
if cat_name.lower() == 'clothing':
clothing_total += qty * price
elif cat_name.lower() == 'electronics':
electronics_total += qty * price
elif cat_name.lower() == 'books':
books_total += qty * price
else:
other_total += qty * price
print('--- REPORTS SUMMARY ---')
print('Users count:', tot_users)
print('Products catalog count:', tot_products)
print('Orders count:', tot_orders)
print('Total Revenue generated:', total_rev)
print('Total Discount Given:', total_discount_given)
print('Total Shipping Charged:', total_shipping_charged)
print('--- Category Sales Revenue ---')
print('Clothing:', clothing_total)
print('Electronics:', electronics_total)
print('Books:', books_total)
print('Other:', other_total)
else:
print('Invalid Option! Please try again.')