feat: implement legacy shop management system and add task documentation files
CI Check / lint-and-check (push) Failing after 9s
CI Check / lint-and-check (push) Failing after 9s
This commit is contained in:
@@ -0,0 +1,583 @@
|
||||
# -*- 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.')
|
||||
Reference in New Issue
Block a user