2025-06-01 10:05:16 +00:00

168 lines
4.7 KiB
Python

from datetime import date, datetime
from typing import Any, Optional
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session
from app.api.deps import get_current_user
from app.crud import category, item, transaction
from app.db.utils import get_db
from app.models.user import User
from app.schemas.report import (
CategorySummaryItem,
CategorySummaryReport,
InventoryValueItem,
InventoryValueReport,
LowStockItem,
LowStockReport,
TransactionSummaryItem,
TransactionSummaryReport,
)
router = APIRouter()
@router.get("/inventory-value", response_model=InventoryValueReport)
def get_inventory_value(
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
) -> Any:
"""
Generate inventory value report.
"""
items_db = item.get_multi(db)
inventory_items = []
total_value = 0.0
for item_db in items_db:
item_value = item_db.price * item_db.quantity
total_value += item_value
inventory_items.append(
InventoryValueItem(
id=item_db.id,
name=item_db.name,
sku=item_db.sku,
quantity=item_db.quantity,
price=item_db.price,
total_value=item_value
)
)
return InventoryValueReport(
total_inventory_value=total_value,
items=inventory_items,
report_date=datetime.utcnow()
)
@router.get("/category-summary", response_model=CategorySummaryReport)
def get_category_summary(
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
) -> Any:
"""
Generate category summary report.
"""
# Get all categories
categories_db = category.get_multi(db)
summary_items = []
for cat in categories_db:
# Get items in this category
items_in_category = item.get_by_category_id(db, category_id=cat.id)
# Calculate totals
item_count = len(items_in_category)
total_value = sum(i.price * i.quantity for i in items_in_category)
avg_price = sum(i.price for i in items_in_category) / item_count if item_count > 0 else 0
summary_items.append(
CategorySummaryItem(
category_id=cat.id,
category_name=cat.name,
item_count=item_count,
total_value=total_value,
average_price=avg_price
)
)
return CategorySummaryReport(
categories=summary_items,
report_date=datetime.utcnow()
)
@router.get("/low-stock", response_model=LowStockReport)
def get_low_stock_report(
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
) -> Any:
"""
Generate low stock report.
"""
# Get items with stock below reorder level
low_stock_items_db = item.get_low_stock_items(db)
low_stock_items = []
for item_db in low_stock_items_db:
low_stock_items.append(
LowStockItem(
id=item_db.id,
name=item_db.name,
sku=item_db.sku,
quantity=item_db.quantity,
reorder_level=item_db.reorder_level,
category_name=item_db.category.name if item_db.category else None
)
)
return LowStockReport(
low_stock_items=low_stock_items,
report_date=datetime.utcnow()
)
@router.get("/transaction-summary", response_model=TransactionSummaryReport)
def get_transaction_summary(
start_date: date = Query(..., description="Start date for the report period"),
end_date: Optional[date] = Query(None, description="End date for the report period"),
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
) -> Any:
"""
Generate transaction summary report.
"""
if end_date is None:
end_date = date.today()
if start_date > end_date:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Start date must be before end date",
)
# Get transaction summary by type
summary_data = transaction.get_summary_by_type(
db, start_date=start_date, end_date=end_date
)
summary_items = [
TransactionSummaryItem(
transaction_type=item["transaction_type"],
count=item["count"],
total_quantity=item["total_quantity"],
total_value=item["total_value"]
)
for item in summary_data
]
return TransactionSummaryReport(
start_date=start_date,
end_date=end_date,
transactions=summary_items,
report_date=datetime.utcnow()
)