from logging import getLogger from fastapi import APIRouter, Depends from models.sales import OrderWeb from models.user import User from auth.security import get_current_user from config.messages import ErrorResponse, SuccessResponse from utils.responses import error_response, success_response from services.order_service import ( compare_prices, fetch_sorted_products, push_items_to_toteat, get_active_sale_id, update_reward_progress, create_sale_record, ) logger = getLogger(__name__) order_router = APIRouter() @order_router.post("/send") async def printer_order(order: OrderWeb, current_user: User = Depends(get_current_user)): """Procesa un pedido: valida, registra en Toteat POS y persiste en BD.""" items, table = order.items, order.table logger.info(f"Order received from {current_user.email} for table {table}") # 1. Validación de entrada if not items or not table: logger.warning(f"Missing fields from {current_user.email}") return error_response(message=ErrorResponse.MISSING_FIELDS, status_code=400) if not isinstance(table, int): logger.warning(f"Invalid table type from {current_user.email}: {type(table)}") return error_response(message=ErrorResponse.INVALID_TABLE_TYPE, status_code=400) # 2. Verificar precios actuales en BD try: products = await fetch_sorted_products(items) items = sorted(items, key=lambda x: x.id) logger.info(f"Retrieved {len(products)} products for table {table}") except Exception as e: return error_response(message=f"Error getting products: {e}", status_code=500) price_changes = compare_prices(products, items) if price_changes: return success_response( data=price_changes, message="El estado de los productos y items coincide con el de la venta", status_code=409, ) # 3. Registrar en Toteat POS try: product_errors, beers = push_items_to_toteat(items, products, table, current_user.name) except Exception as e: return error_response(message=f"Error with Toteat integration: {e}", status_code=500) if product_errors: logger.error(f"Product errors for table {table}: {product_errors}") return error_response(error={"errors": product_errors}, message=ErrorResponse.PRODUCT_ADD_ERROR, status_code=424) # 4. Venta activa de la mesa try: active_sale_id = get_active_sale_id(table) if not active_sale_id: return error_response(message=f"No active sale found for table {table}", status_code=404) logger.info(f"Active sale for table {table}: {active_sale_id}") except Exception as e: return error_response(message=f"Error retrieving active sale: {e}", status_code=500) # 5. Puntos de fidelización (no bloquea el pedido si falla) new_progress = update_reward_progress(current_user, beers) # 6. Persistir en BD try: sale_id = create_sale_record(order, active_sale_id, items) if sale_id <= 0: return error_response(message="Failed to create sale record", status_code=500) except Exception as e: return error_response(message=f"Error creating sale record: {e}", status_code=500) logger.info(f"Order completed for table {table}, sale ID: {sale_id}") return success_response(data={"new_progress": new_progress}, message=SuccessResponse.ORDER_SUCCESS)