order and api and more

This commit is contained in:
2025-04-17 00:09:16 -04:00
parent 593e8960b7
commit 21408af48c
31 changed files with 1924 additions and 542 deletions

214
app/routes/order_routes.py Normal file
View File

@ -0,0 +1,214 @@
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)}")

View File

@ -8,18 +8,16 @@ from app.schemas.box import BoxCreate, BoxUpdate, BoxDelete, BoxList, OpenBoxCre
from app.models.game import Game as GameModel
from app.schemas.game import GameCreate, GameUpdate, GameDelete, GameList, GameInDB
from app.models.card import Card as CardModel
from app.schemas.card import CardCreate, CardUpdate, CardDelete, CardList, CardInDB
from app.services import CardService, OrderService
from app.services.file_processing_service import FileProcessingService
from app.services.external_api.tcgplayer.tcgplayer_inventory_service import TCGPlayerInventoryService
from app.routes.set_label_routes import router as set_label_router
from app.routes.order_routes import router as order_router
router = APIRouter(prefix="/api")
# Initialize services
card_service = CardService()
order_service = OrderService()
file_processing_service = FileProcessingService()
tcgplayer_inventory_service = TCGPlayerInventoryService()
# Include set label routes
router.include_router(set_label_router)
# Include order routes
router.include_router(order_router)
# ============================================================================
# Health Check & Root Endpoints
@ -32,80 +30,6 @@ async def root():
async def health():
return {"status": "ok"}
# ============================================================================
# Card Management Endpoints
# ============================================================================
@router.get("/cards", response_model=CardList)
async def get_cards(
db: Session = Depends(get_db),
page: int = 1,
limit: int = 10,
type: str = None,
id: int = None
):
skip = (page - 1) * limit
cards = card_service.get_all(db, skip=skip, limit=limit)
total = db.query(CardModel).count()
return {
"cards": cards,
"total": total,
"page": page,
"limit": limit
}
@router.post("/cards", response_model=CardInDB)
async def create_card(card: CardCreate, db: Session = Depends(get_db)):
try:
created_card = card_service.create(db, card.dict())
return created_card
except Exception as e:
raise HTTPException(status_code=400, detail=str(e))
@router.put("/cards/{card_id}", response_model=CardInDB)
async def update_card(card_id: int, card: CardUpdate, db: Session = Depends(get_db)):
db_card = card_service.get(db, card_id)
if not db_card:
raise HTTPException(status_code=404, detail="Card not found")
try:
updated_card = card_service.update(db, db_card, card.dict(exclude_unset=True))
return updated_card
except Exception as e:
raise HTTPException(status_code=400, detail=str(e))
@router.delete("/cards/{card_id}", response_model=CardDelete)
async def delete_card(card_id: int, db: Session = Depends(get_db)):
success = card_service.delete(db, card_id)
if not success:
raise HTTPException(status_code=404, detail="Card not found")
return {"message": "Card deleted successfully"}
# ============================================================================
# Order Management Endpoints
# ============================================================================
@router.post("/orders")
async def create_order(order_data: dict, card_ids: list[int], db: Session = Depends(get_db)):
try:
order = order_service.create_order_with_cards(db, order_data, card_ids)
return order
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.get("/orders")
async def get_orders(
db: Session = Depends(get_db),
page: int = 1,
limit: int = 10
):
skip = (page - 1) * limit
orders = order_service.get_orders_with_cards(db, skip=skip, limit=limit)
return {
"orders": orders,
"page": page,
"limit": limit
}
# ============================================================================
# File Management Endpoints
# ============================================================================

View File

@ -0,0 +1,52 @@
from fastapi import APIRouter, HTTPException, Depends
from app.services.set_label_service import SetLabelService
from app.services.label_printer_service import LabelPrinterService
from typing import List, Optional
import asyncio
from app.db.database import get_db
from sqlalchemy.orm import Session
from pydantic import BaseModel
class SetLabelRequest(BaseModel):
sets: List[str]
router = APIRouter(prefix="/set-labels")
set_label_service = SetLabelService()
label_printer_service = LabelPrinterService(printer_api_url="http://192.168.1.110:8000")
@router.post("/generate")
async def generate_set_labels(request: SetLabelRequest):
"""
Generate PDF labels for the specified MTG sets.
Args:
request: Request body containing list of set codes to generate labels for
Returns:
Message indicating success or failure
"""
try:
set_pdfs = await set_label_service.generate_labels(request.sets)
for set_pdf in set_pdfs:
success = await label_printer_service.print_file(set_pdf, label_size="dk1201", label_type="set_label")
if not success:
raise HTTPException(status_code=500, detail=f"Failed to print")
return {
"message": "Labels printed successfully"
}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.get("/available-sets")
async def get_available_sets(db: Session = Depends(get_db)):
"""
Get a list of available MTG sets that can be used for label generation.
Returns:
List of set codes and their names
"""
try:
sets = await set_label_service.get_available_sets(db)
return sets
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))