Files
Control_Panel/server/inventory/router.py
T
2026-07-15 18:37:19 +09:00

145 lines
5.3 KiB
Python

from fastapi import APIRouter, HTTPException
from pydantic import BaseModel, Field
from typing import List, Optional
from .db_manager import (
add_material_property,
update_material_property,
delete_material_property,
get_all_material_properties,
get_material_property_by_id,
add_inventory_to_db,
update_inventory_in_db,
deplete_inventory_in_db,
get_all_inventory_from_db,
get_inventory_details_from_db
)
from .analysis import calculate_cost_analysis
router = APIRouter(prefix="/inventory", tags=["inventory"])
# --- Pydantic Schemas ---
class MaterialPropertySchema(BaseModel):
id: Optional[int] = None
material_code: str
material_name: str
material_type: str
density: float
remarks: Optional[str] = None
class InventorySchema(BaseModel):
id: Optional[int] = None
material_id: int
receipt_date: str # YYYY-MM-DD
receipt_quantity: float
usage_quantity: Optional[float] = 0.0
stock: Optional[float] = None
unit_cost: float
remarks: Optional[str] = None
is_depleted: Optional[int] = 0
supplier_id: Optional[int] = None
item_name: Optional[str] = None
item_number: Optional[str] = None
class AnalysisInputSchema(BaseModel):
yarn_inventory_id: int
bond_inventory_id: Optional[int] = None
yarn_diameter_micron: Optional[float] = 7.0
yarn_k: Optional[float] = 12.0
ports: Optional[float] = 40.0
cycle_time_hz: Optional[float] = 8.0
cut_length_mm: Optional[float] = 6.0
work_hours_day: Optional[float] = 16.0
work_days_month: Optional[float] = 20.0
num_machines: Optional[float] = 2.0
bond_percentage: Optional[float] = 3.0
class CostAnalysisRequestSchema(BaseModel):
inputs: AnalysisInputSchema
targetProductionQuantity: Optional[float] = None
# --- Material Properties APIs ---
@router.post("/materials", response_model=dict)
def create_material_property(material: MaterialPropertySchema):
result = add_material_property(material.dict())
if result is None:
raise HTTPException(status_code=500, detail="Failed to create material property")
return {"id": result, "status": "success"}
@router.put("/materials/{material_id}", response_model=dict)
def update_material(material_id: int, material: MaterialPropertySchema):
data = material.dict()
data['id'] = material_id
success = update_material_property(data)
if not success:
raise HTTPException(status_code=500, detail="Failed to update material property")
return {"status": "success"}
@router.delete("/materials/{material_id}", response_model=dict)
def delete_material(material_id: int):
success = delete_material_property(material_id)
if not success:
raise HTTPException(status_code=400, detail="Failed to delete material property. Check if it's in use.")
return {"status": "success"}
@router.get("/materials", response_model=List[MaterialPropertySchema])
def list_material_properties():
return get_all_material_properties()
@router.get("/materials/{material_id}", response_model=MaterialPropertySchema)
def get_material_property(material_id: int):
material = get_material_property_by_id(material_id)
if not material:
raise HTTPException(status_code=404, detail="Material property not found")
return material
# --- Inventory APIs ---
@router.post("/", response_model=dict)
def create_inventory(inventory: InventorySchema):
result = add_inventory_to_db(inventory.dict())
if result is None:
raise HTTPException(status_code=500, detail="Failed to create inventory record")
return {"id": result, "status": "success"}
@router.put("/{inventory_id}", response_model=dict)
def update_inventory(inventory_id: int, inventory: InventorySchema):
data = inventory.dict()
data['id'] = inventory_id
success = update_inventory_in_db(data)
if not success:
raise HTTPException(status_code=500, detail="Failed to update inventory record")
return {"status": "success"}
@router.put("/{inventory_id}/deplete", response_model=dict)
def deplete_inventory(inventory_id: int):
success = deplete_inventory_in_db(inventory_id)
if not success:
raise HTTPException(status_code=500, detail="Failed to deplete inventory")
return {"status": "success"}
@router.get("/", response_model=List[dict])
def list_inventory():
return get_all_inventory_from_db()
@router.get("/{inventory_id}", response_model=dict)
def get_inventory_details(inventory_id: int):
details = get_inventory_details_from_db(inventory_id)
if not details:
raise HTTPException(status_code=404, detail="Inventory details not found")
return details
# --- Cost Analysis APIs ---
@router.post("/analysis/calculate", response_model=dict)
def cost_analysis(request_data: CostAnalysisRequestSchema):
try:
inputs_dict = request_data.inputs.dict()
# Null 문자열 파라미터 방어용 가공
if not inputs_dict.get("bond_inventory_id"):
inputs_dict["bond_inventory_id"] = "null"
result = calculate_cost_analysis(inputs_dict, request_data.targetProductionQuantity)
return result
except ValueError as val_err:
raise HTTPException(status_code=400, detail=str(val_err))
except Exception as exc:
raise HTTPException(status_code=500, detail=f"Internal calculations failed: {exc}")