i think most of this works lole
This commit is contained in:
165
app/routes/inventory_management_routes.py
Normal file
165
app/routes/inventory_management_routes.py
Normal file
@ -0,0 +1,165 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
from app.db.database import get_db
|
||||
from app.services.service_manager import ServiceManager
|
||||
from app.contexts.inventory_item import InventoryItemContextFactory
|
||||
from app.schemas.transaction import PurchaseTransactionCreate, SaleTransactionCreate, TransactionResponse
|
||||
from typing import List
|
||||
router = APIRouter(prefix="/inventory")
|
||||
|
||||
service_manager = ServiceManager()
|
||||
|
||||
# Sealed Routes
|
||||
@router.get("/sealed/boxes")
|
||||
async def get_sealed_boxes(
|
||||
skip: int = 0,
|
||||
limit: int = 100,
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
sealed_box_service = service_manager.get_service("sealed_box")
|
||||
raw_boxes = sealed_box_service.get_all(db, skip=skip, limit=limit)
|
||||
boxes = []
|
||||
for box in raw_boxes:
|
||||
inventory_item = InventoryItemContextFactory(db).get_context(box.inventory_item)
|
||||
boxes.append(inventory_item)
|
||||
return boxes
|
||||
|
||||
@router.get("/sealed/boxes/{sealed_box_id}")
|
||||
async def get_sealed_box(
|
||||
sealed_box_id: int,
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
sealed_box_service = service_manager.get_service("sealed_box")
|
||||
sealed_box = sealed_box_service.get(db, sealed_box_id)
|
||||
return InventoryItemContextFactory(db).get_context(sealed_box.inventory_item)
|
||||
|
||||
@router.post("/sealed/boxes")
|
||||
async def create_sealed_box(
|
||||
product_id: int,
|
||||
cost_basis: float,
|
||||
case_id: int = None,
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
try:
|
||||
sealed_box_service = service_manager.get_service("sealed_box")
|
||||
sealed_box = await sealed_box_service.create_sealed_box(db, product_id, cost_basis, case_id)
|
||||
return InventoryItemContextFactory(db).get_context(sealed_box.inventory_item)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
@router.post("/sealed/boxes/{sealed_box_id}/open")
|
||||
async def open_sealed_box(
|
||||
sealed_box_id: int,
|
||||
manabox_file_upload_ids: List[int],
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
try:
|
||||
inventory_service = service_manager.get_service("inventory")
|
||||
sealed_box_service = service_manager.get_service("sealed_box")
|
||||
file_service = service_manager.get_service("file")
|
||||
sealed_box = sealed_box_service.get(db, sealed_box_id)
|
||||
manabox_file_uploads = []
|
||||
for manabox_file_upload_id in manabox_file_upload_ids:
|
||||
manabox_file_upload = file_service.get_file(db, manabox_file_upload_id)
|
||||
manabox_file_uploads.append(manabox_file_upload)
|
||||
success = await inventory_service.process_manabox_import_staging(db, manabox_file_uploads, sealed_box)
|
||||
if not success:
|
||||
raise HTTPException(status_code=400, detail="Failed to process Manabox import staging")
|
||||
return {"message": "Manabox import staging processed successfully"}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
@router.get("/sealed/cases")
|
||||
async def get_sealed_cases(
|
||||
skip: int = 0,
|
||||
limit: int = 100,
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
sealed_case_service = service_manager.get_service("sealed_case")
|
||||
raw_cases = sealed_case_service.get_all(db, skip=skip, limit=limit)
|
||||
cases = []
|
||||
for case in raw_cases:
|
||||
inventory_item = InventoryItemContextFactory(db).get_context(case.inventory_item)
|
||||
cases.append(inventory_item)
|
||||
return cases
|
||||
|
||||
@router.get("/sealed/cases/{sealed_case_id}")
|
||||
async def get_sealed_case(
|
||||
sealed_case_id: int,
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
sealed_case_service = service_manager.get_service("sealed_case")
|
||||
sealed_case = sealed_case_service.get(db, sealed_case_id)
|
||||
return InventoryItemContextFactory(db).get_context(sealed_case.inventory_item)
|
||||
|
||||
@router.post("/sealed/cases")
|
||||
async def create_sealed_case(
|
||||
product_id: int,
|
||||
cost_basis: float,
|
||||
num_boxes: int,
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
try:
|
||||
sealed_case_service = service_manager.get_service("sealed_case")
|
||||
sealed_case = await sealed_case_service.create_sealed_case(db, product_id, cost_basis, num_boxes)
|
||||
return InventoryItemContextFactory(db).get_context(sealed_case.inventory_item)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
@router.post("/sealed/cases/{sealed_case_id}/open")
|
||||
async def open_sealed_case(
|
||||
sealed_case_id: int,
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
try:
|
||||
sealed_case_service = service_manager.get_service("sealed_case")
|
||||
sealed_case = sealed_case_service.get(db, sealed_case_id)
|
||||
await sealed_case_service.open_sealed_case(db, sealed_case)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
# Transaction Routes
|
||||
@router.post("/transactions/purchase")
|
||||
async def create_purchase_transaction(
|
||||
transaction_data: PurchaseTransactionCreate,
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
inventory_service = service_manager.get_service("inventory")
|
||||
transaction = await inventory_service.create_purchase_transaction(db, transaction_data)
|
||||
return transaction
|
||||
|
||||
@router.post("/transactions/sale")
|
||||
async def create_sale_transaction(
|
||||
transaction_data: SaleTransactionCreate,
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
inventory_service = service_manager.get_service("inventory")
|
||||
transaction = await inventory_service.create_sale_transaction(db, transaction_data)
|
||||
return transaction
|
||||
|
||||
@router.post("/customers")
|
||||
async def create_customer(
|
||||
customer_name: str,
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
inventory_service = service_manager.get_service("inventory")
|
||||
customer = await inventory_service.create_customer(db, customer_name)
|
||||
return customer
|
||||
|
||||
@router.post("/vendors")
|
||||
async def create_vendor(
|
||||
vendor_name: str,
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
inventory_service = service_manager.get_service("inventory")
|
||||
vendor = await inventory_service.create_vendor(db, vendor_name)
|
||||
return vendor
|
||||
|
||||
@router.post("/marketplaces")
|
||||
async def create_marketplace(
|
||||
marketplace_name: str,
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
inventory_service = service_manager.get_service("inventory")
|
||||
marketplace = await inventory_service.create_marketplace(db, marketplace_name)
|
||||
return marketplace
|
@ -1,24 +1,78 @@
|
||||
from fastapi import APIRouter, Depends, UploadFile, File, HTTPException
|
||||
from fastapi import APIRouter, Depends, UploadFile, File, HTTPException, Form
|
||||
from sqlalchemy.orm import Session
|
||||
from app.db.database import get_db
|
||||
from app.services.service_manager import ServiceManager
|
||||
import csv
|
||||
import io
|
||||
|
||||
router = APIRouter(prefix="/manabox")
|
||||
|
||||
service_manager = ServiceManager()
|
||||
|
||||
REQUIRED_HEADERS = {
|
||||
'Name', 'Set code', 'Set name', 'Collector number', 'Foil', 'Rarity',
|
||||
'Quantity', 'ManaBox ID', 'Scryfall ID', 'Purchase price', 'Misprint',
|
||||
'Altered', 'Condition', 'Language', 'Purchase price currency'
|
||||
}
|
||||
|
||||
def is_valid_csv(file: UploadFile) -> tuple[bool, str]:
|
||||
# Check if filename ends with .csv
|
||||
if not file.filename.lower().endswith('.csv'):
|
||||
return False, "File must have a .csv extension"
|
||||
|
||||
try:
|
||||
# Try to read the content as CSV
|
||||
content = file.file.read()
|
||||
# Reset file pointer for later use
|
||||
file.file.seek(0)
|
||||
|
||||
# Try to parse the content as CSV
|
||||
csv_reader = csv.reader(io.StringIO(content.decode('utf-8')))
|
||||
|
||||
# Get headers from first row
|
||||
headers = set(next(csv_reader))
|
||||
|
||||
# Check for missing headers
|
||||
missing_headers = REQUIRED_HEADERS - headers
|
||||
if missing_headers:
|
||||
return False, f"Missing required columns: {', '.join(missing_headers)}"
|
||||
|
||||
# Check for extra headers
|
||||
extra_headers = headers - REQUIRED_HEADERS
|
||||
if extra_headers:
|
||||
return False, f"Unexpected columns found: {', '.join(extra_headers)}"
|
||||
|
||||
return True, "Valid CSV format"
|
||||
except (csv.Error, UnicodeDecodeError) as e:
|
||||
return False, f"Invalid CSV format: {str(e)}"
|
||||
except StopIteration:
|
||||
return False, "Empty file"
|
||||
|
||||
@router.post("/process-csv")
|
||||
async def process_manabox_csv(
|
||||
file: UploadFile = File(...),
|
||||
source: str = Form(...),
|
||||
description: str = Form(...),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
try:
|
||||
is_valid, error_message = is_valid_csv(file)
|
||||
if not is_valid:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=error_message
|
||||
)
|
||||
|
||||
content = await file.read()
|
||||
|
||||
metadata = {
|
||||
"source": source,
|
||||
"description": description
|
||||
}
|
||||
|
||||
manabox_service = service_manager.get_service("manabox")
|
||||
|
||||
success = await manabox_service.process_manabox_csv(db, content)
|
||||
success = await manabox_service.process_manabox_csv(db, content, metadata)
|
||||
|
||||
if not success:
|
||||
raise HTTPException(status_code=400, detail="Failed to process CSV file")
|
||||
@ -26,4 +80,14 @@ async def process_manabox_csv(
|
||||
return {"message": "CSV processed successfully"}
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
@router.get("/manabox-file-uploads")
|
||||
async def get_manabox_file_uploads(
|
||||
skip: int = 0,
|
||||
limit: int = 100,
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
file_service = service_manager.get_service("file")
|
||||
files = await file_service.list_files(db, skip=skip, limit=limit, file_type="manabox")
|
||||
return files
|
@ -6,7 +6,7 @@ from app.schemas.file import FileCreate, FileUpdate, FileDelete, FileList, FileI
|
||||
from app.routes.set_label_routes import router as set_label_router
|
||||
from app.routes.order_routes import router as order_router
|
||||
from app.routes.manabox_routes import router as manabox_router
|
||||
|
||||
from app.routes.inventory_management_routes import router as inventory_management_router
|
||||
router = APIRouter(prefix="/api")
|
||||
|
||||
# Include set label routes
|
||||
@ -18,6 +18,9 @@ router.include_router(order_router)
|
||||
# Include manabox routes
|
||||
router.include_router(manabox_router)
|
||||
|
||||
# Include inventory management routes
|
||||
router.include_router(inventory_management_router)
|
||||
|
||||
# ============================================================================
|
||||
# Health Check & Root Endpoints
|
||||
# ============================================================================
|
||||
|
Reference in New Issue
Block a user