Manager + Client fixes

This commit is contained in:
helldh 2026-02-15 19:09:27 +03:00
parent c0727d7b59
commit 2fff742651
2 changed files with 641 additions and 37 deletions

255
src/db.py
View file

@ -118,31 +118,260 @@ def get_items(*, cursor):
@do_request(autocommit=True)
def create_request(item_id: int, user: User, **kwargs):
def create_request(item_id: int, quantity: int, user: User,
date_from: str = None, date_to: str = None,
notes: str = None, *, cursor):
"""
Создать заявку/заказ
Создать новую заявку/заказ
TODO: Адаптировать под конкретную предметную область
Args:
item_id: ID элемента (товар, номер, услуга)
user: Пользователь создающий заявку
**kwargs: Дополнительные параметры (даты, количество, etc.)
item_id: ID товара/услуги
quantity: Количество
user: Объект пользователя
date_from: Дата начала (YYYY-MM-DD) или None
date_to: Дата окончания (YYYY-MM-DD) или None
notes: Дополнительные заметки
cursor: Курсор БД (автоматически через декоратор)
Returns:
True если успешно, False если ошибка
"""
# TODO: Реализовать вашу логику создания заявки
pass
try:
# 1. Проверяем существование товара и его доступность
cursor.execute("""
SELECT id, name, price, quantity, status
FROM items
WHERE id = %s;
""", (item_id,))
item = cursor.fetchone()
if not item:
print(f"Error: Item with id={item_id} not found")
return False
item_db_id, item_name, item_price, item_quantity, item_status = item
# 2. Проверяем статус товара
if item_status not in ['available', 'reserved']:
print(f"Error: Item '{item_name}' is not available (status: {item_status})")
return False
# 3. Проверяем количество (если товар физический)
if item_quantity < quantity:
print(f"Error: Insufficient quantity. Available: {item_quantity}, requested: {quantity}")
return False
# 4. Вычисляем total_price
total_price = float(item_price) * quantity
# 5. Создаём заявку
cursor.execute("""
INSERT INTO requests (user_id, item_id, quantity, date_from, date_to,
status, total_price, notes)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
RETURNING id;
""", (user.id, item_id, quantity, date_from, date_to,
'pending', total_price, notes))
request_id = cursor.fetchone()[0]
print(f"Success: Request #{request_id} created for user {user.name}")
return True
except Exception as e:
print(f"Error creating request: {e}")
return False
@do_request()
def get_user_requests(user_id: int, *, cursor):
"""
Получить заявки/заказы пользователя
Получить все заявки пользователя
TODO: Заменить на вашу логику
Args:
user_id: ID пользователя
Returns:
List of tuples или None
"""
cursor.execute("""
SELECT *
FROM requests
WHERE user_id = %s;
SELECT
r.id,
r.created_at,
i.name AS item_name,
r.quantity,
r.total_price,
r.date_from,
r.date_to,
r.status,
r.notes
FROM requests r
JOIN items i ON r.item_id = i.id
WHERE r.user_id = %s
ORDER BY r.created_at DESC;
""", (user_id,))
return cursor.fetchall()
@do_request(autocommit=True)
def update_request_status(request_id: int, new_status: str, *, cursor):
"""
Обновить статус заявки (для менеджера/администратора)
Args:
request_id: ID заявки
new_status: Новый статус ('pending', 'approved', 'rejected', 'completed', 'cancelled')
Returns:
True если успешно, False если ошибка
"""
valid_statuses = ['pending', 'approved', 'rejected', 'completed', 'cancelled']
if new_status not in valid_statuses:
print(f"Error: Invalid status '{new_status}'. Must be one of: {valid_statuses}")
return False
try:
cursor.execute("""
UPDATE requests
SET status = %s, updated_at = CURRENT_TIMESTAMP
WHERE id = %s;
""", (new_status, request_id))
if cursor.rowcount == 0:
print(f"Error: Request #{request_id} not found")
return False
print(f"Success: Request #{request_id} status updated to '{new_status}'")
return True
except Exception as e:
print(f"Error updating request status: {e}")
return False
@do_request()
def get_all_requests(status_filter: str = None, *, cursor):
"""
Получить все заявки (для администратора/менеджера)
Args:
status_filter: Фильтр по статусу (опционально)
Returns:
List of tuples
"""
if status_filter:
cursor.execute("""
SELECT
r.id,
r.created_at,
u.name AS user_name,
u.email AS user_email,
i.name AS item_name,
r.quantity,
r.total_price,
r.date_from,
r.date_to,
r.status
FROM requests r
JOIN users u ON r.user_id = u.id
JOIN items i ON r.item_id = i.id
WHERE r.status = %s
ORDER BY r.created_at DESC;
""", (status_filter,))
else:
cursor.execute("""
SELECT
r.id,
r.created_at,
u.name AS user_name,
u.email AS user_email,
i.name AS item_name,
r.quantity,
r.total_price,
r.date_from,
r.date_to,
r.status
FROM requests r
JOIN users u ON r.user_id = u.id
JOIN items i ON r.item_id = i.id
ORDER BY r.created_at DESC;
""")
return cursor.fetchall()
@do_request()
def search_items(search_term: str, *, cursor):
"""
Поиск товаров по названию или описанию
Args:
search_term: Поисковый запрос
Returns:
List of tuples
"""
cursor.execute("""
SELECT
i.id,
i.name,
i.description,
i.price,
i.quantity,
i.status,
c.name AS category_name
FROM items i
LEFT JOIN categories c ON i.category_id = c.id
WHERE i.name ILIKE %s OR i.description ILIKE %s
ORDER BY i.name;
""", (f'%{search_term}%', f'%{search_term}%'))
return cursor.fetchall()
@do_request()
def get_items_by_category(category_id: int, *, cursor):
"""
Получить товары по категории
Args:
category_id: ID категории
Returns:
List of tuples
"""
cursor.execute("""
SELECT
i.id,
i.name,
i.description,
i.price,
i.quantity,
i.status
FROM items i
WHERE i.category_id = %s AND i.status = 'available'
ORDER BY i.name;
""", (category_id,))
return cursor.fetchall()
@do_request()
def get_all_categories(*, cursor):
"""
Получить все категории
Returns:
List of tuples (id, name)
"""
cursor.execute("""
SELECT id, name, description
FROM categories
ORDER BY name;
""")
return cursor.fetchall()