order and api and more
This commit is contained in:
214
app/routes/order_routes.py
Normal file
214
app/routes/order_routes.py
Normal 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)}")
|
@ -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
|
||||
# ============================================================================
|
||||
|
52
app/routes/set_label_routes.py
Normal file
52
app/routes/set_label_routes.py
Normal 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))
|
Reference in New Issue
Block a user