초기화
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
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}")
|
||||
Reference in New Issue
Block a user