from fastapi import APIRouter, HTTPException, Depends, Query from app.services.external_api.tcgplayer.order_management_service import OrderManagementService from app.services.label_printer_service import LabelPrinterService from app.services.regular_printer_service import RegularPrinterService from app.services.address_label_service import AddressLabelService from typing import List, Optional, Literal from datetime import datetime from pydantic import BaseModel, Field from enum import Enum from app.schemas.tcgplayer import TCGPlayerAPIOrderSummary, TCGPlayerAPIOrder from app.services.service_manager import ServiceManager class SearchRange(str, Enum): LAST_WEEK = "LastWeek" LAST_MONTH = "LastMonth" LAST_THREE_MONTHS = "LastThreeMonths" LAST_FOUR_MONTHS = "LastFourMonths" LAST_TWO_YEARS = "LastTwoYears" class LabelType(str, Enum): DK1201 = "dk1201" DK1241 = "dk1241" # Initialize service manager service_manager = ServiceManager() # Initialize router router = APIRouter(prefix="/orders") @router.get("/", response_model=List[TCGPlayerAPIOrderSummary]) async def get_orders( search_range: SearchRange = SearchRange.LAST_THREE_MONTHS, open_only: bool = False ) -> List[TCGPlayerAPIOrderSummary]: """ Retrieve orders from TCGPlayer based on search criteria. Args: search_range: Time range to search for orders open_only: Whether to only return open orders Returns: List of orders matching the search criteria """ try: order_management = service_manager.get_service('order_management') orders = await order_management.get_orders(search_range, open_only) return orders except Exception as e: raise HTTPException(status_code=500, detail=f"Failed to fetch orders: {str(e)}") @router.get("/{order_id}", response_model=TCGPlayerAPIOrder) async def get_order(order_id: str) -> TCGPlayerAPIOrder: """ Retrieve a specific order by ID. Args: order_id: The TCGPlayer order number Returns: The requested order details """ try: order_management = service_manager.get_service('order_management') order = await order_management.get_order(order_id) if not order: raise HTTPException(status_code=404, detail=f"Order {order_id} not found") return order except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=f"Failed to fetch order: {str(e)}") @router.post("/generate-pull-sheets") async def generate_pull_sheets( order_ids: Optional[List[str]] = None, all_open_orders: bool = False ) -> dict: """ Generate and print pull sheets for the specified orders. Args: order_ids: List of TCGPlayer order numbers (optional if all_open_orders is True) all_open_orders: If True, generate pull sheets for all orders (ignores order_ids) Returns: Success status of the operation """ try: order_management = service_manager.get_service('order_management') if not all_open_orders and not order_ids: raise HTTPException( status_code=400, detail="Either order_ids must be provided or all_open_orders must be True" ) if all_open_orders: order_ids = await order_management.get_order_ids(search_range="LastWeek", open_only=True) pull_sheet = await order_management.get_pull_sheet(order_ids) pull_sheet_file = await order_management.save_file( pull_sheet, f"pull_sheet_{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.csv" ) pull_sheet_service = service_manager.get_service('pull_sheet') pull_sheet_pdf = await pull_sheet_service.generate_pull_sheet_pdf(pull_sheet_file) regular_printer = service_manager.get_service('regular_printer') success = await regular_printer.print_file(pull_sheet_pdf) return {"success": success} except Exception as e: raise HTTPException(status_code=500, detail=f"Failed to generate pull sheet: {str(e)}") @router.post("/generate-packing-slips") async def generate_packing_slips( order_ids: Optional[List[str]] = None, all_open_orders: bool = False ) -> dict: """ Generate and print packing slips for the specified orders. Args: order_ids: List of TCGPlayer order numbers (optional if all_open_orders is True) all_open_orders: If True, generate packing slips for all orders (ignores order_ids) Returns: Success status of the operation """ try: if not all_open_orders and not order_ids: raise HTTPException( status_code=400, detail="Either order_ids must be provided or all_open_orders must be True" ) # TODO: Add logic to fetch all orders when all_open_orders is True if all_open_orders: order_management = service_manager.get_service('order_management') order_ids = await order_management.get_order_ids(search_range="LastWeek", open_only=True) packing_slip = await order_management.get_packing_slip(order_ids) packing_slip_file = await order_management.save_file( packing_slip, f"packing_slip_{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.pdf" ) label_printer = service_manager.get_service('label_printer') success = await label_printer.print_file( packing_slip_file, label_size="dk1241", label_type="packing_slip" ) return {"success": success} except Exception as e: raise HTTPException(status_code=500, detail=f"Failed to generate packing slip: {str(e)}") @router.post("/generate-address-labels") async def generate_address_labels( order_ids: Optional[List[str]] = None, all_open_orders: bool = False, label_type: LabelType = LabelType.DK1201 ) -> dict: """ Generate and print address labels for the specified orders. Args: order_ids: List of TCGPlayer order numbers (optional if all_open_orders is True) all_open_orders: If True, generate address labels for all orders (ignores order_ids) label_type: Type of label to generate (dk1201 or dk1241) Returns: Success status of the operation """ try: order_management = service_manager.get_service('order_management') if not all_open_orders and not order_ids: raise HTTPException( status_code=400, detail="Either order_ids must be provided or all_open_orders must be True" ) if all_open_orders: order_ids = await order_management.get_order_ids(search_range="LastWeek", open_only=True) shipping_csv = await order_management.get_shipping_csv(order_ids) shipping_csv_file = await order_management.save_file( shipping_csv, f"shipping_csv_{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.csv" ) # Generate PDFs address_label = service_manager.get_service('address_label') pdf_files = await address_label.generate_labels_from_csv( shipping_csv_file, label_type=label_type ) # Print each PDF label_printer = service_manager.get_service('label_printer') for pdf_file in pdf_files: success = await label_printer.print_file( pdf_file, label_size=label_type, label_type="address_label" ) if not success: raise HTTPException( status_code=500, detail=f"Failed to print address label for file {pdf_file}" ) return {"success": True, "message": "Address labels generated and printed successfully"} except Exception as e: raise HTTPException(status_code=500, detail=f"Failed to generate address labels: {str(e)}")