초기화
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from pydantic import BaseModel
|
||||
from typing import List, Dict, Any, Optional
|
||||
from .db_manager import (
|
||||
add_production_plan,
|
||||
add_equipment_assignments_to_plan,
|
||||
get_all_production_plans,
|
||||
find_available_equipment,
|
||||
update_plan_assignment,
|
||||
delete_production_plan,
|
||||
adjust_and_distribute_assignments,
|
||||
update_production_plan
|
||||
)
|
||||
from .helper import calculate_end_date
|
||||
|
||||
router = APIRouter(prefix="/plans", tags=["plans"])
|
||||
|
||||
# --- Pydantic Schemas ---
|
||||
class PlanAssignmentSchema(BaseModel):
|
||||
assignment_id: Optional[int] = None
|
||||
plan_id: Optional[int] = None
|
||||
equipment_id: int
|
||||
start_date: str
|
||||
end_date: str
|
||||
works_on_saturday: bool
|
||||
works_on_sunday: bool
|
||||
|
||||
class PlanSchema(BaseModel):
|
||||
plan_id: Optional[int] = None
|
||||
plan_name: str
|
||||
customer_name: Optional[str] = None
|
||||
customer_id: Optional[int] = None
|
||||
yarn_name: Optional[str] = None
|
||||
yarn_inventory_id: int
|
||||
bond_name: Optional[str] = None
|
||||
bond_inventory_id: Optional[int] = None
|
||||
requested_quantity_kg: float
|
||||
start_date: str
|
||||
end_date: Optional[str] = None
|
||||
production_days: float
|
||||
status: Optional[str] = "Scheduled"
|
||||
|
||||
# Cost & Margin properties
|
||||
hourly_net_cost_per_machine: float
|
||||
hourly_profit_per_machine: float
|
||||
plan_total_material_cost: float
|
||||
yarn_diameter: float
|
||||
yarn_k: float
|
||||
ports: float
|
||||
cycle_time: float
|
||||
cut_length: float
|
||||
work_hours_day: float
|
||||
work_days_month: float
|
||||
num_machines: float
|
||||
plan_net_processing_cost: float
|
||||
plan_company_margin: float
|
||||
plan_processing_fee: float
|
||||
plan_yarn_cost: float
|
||||
plan_bond_cost: float
|
||||
plan_estimated_sales: float
|
||||
|
||||
# Machine allocations
|
||||
equipment_ids: List[int]
|
||||
works_on_saturday: Optional[bool] = False
|
||||
works_on_sunday: Optional[bool] = False
|
||||
|
||||
class AssignmentUpdatePayload(BaseModel):
|
||||
assignment_id: int
|
||||
start_date: str
|
||||
end_date: str
|
||||
works_on_saturday: bool
|
||||
works_on_sunday: bool
|
||||
|
||||
class RedistributionPayload(BaseModel):
|
||||
source_assignment: Dict[str, Any]
|
||||
distribution: Dict[str, int]
|
||||
|
||||
# --- Plan APIs ---
|
||||
@router.post("/", response_model=dict)
|
||||
def create_production_plan(plan: PlanSchema):
|
||||
plan_data = plan.dict()
|
||||
assigned_machine_ids = plan.equipment_ids
|
||||
start_date_str = plan.start_date
|
||||
required_days = plan.production_days
|
||||
|
||||
works_on_saturday = plan.works_on_saturday
|
||||
works_on_sunday = plan.works_on_sunday
|
||||
|
||||
if not assigned_machine_ids or not start_date_str or required_days is None:
|
||||
raise HTTPException(status_code=400, detail="Missing required parameters: equipment_ids, start_date, production_days")
|
||||
|
||||
# 주말 가동 플래그를 고려하여 가용 완료 날짜 계산
|
||||
end_date_str = calculate_end_date(start_date_str, required_days, works_on_saturday, works_on_sunday)
|
||||
plan_data["end_date"] = end_date_str
|
||||
|
||||
plan_id = add_production_plan(plan_data)
|
||||
if not plan_id:
|
||||
raise HTTPException(status_code=500, detail="Failed to add production plan to DB")
|
||||
|
||||
# 설비 할당 정보 생성
|
||||
assignments = [
|
||||
{
|
||||
'equipment_id': eq_id,
|
||||
'start_date': start_date_str,
|
||||
'end_date': end_date_str,
|
||||
'works_on_saturday': works_on_saturday,
|
||||
'works_on_sunday': works_on_sunday
|
||||
} for eq_id in assigned_machine_ids
|
||||
]
|
||||
|
||||
assign_success = add_equipment_assignments_to_plan(plan_id, assignments)
|
||||
if not assign_success:
|
||||
raise HTTPException(status_code=500, detail="Plan was created but equipment assignments failed.")
|
||||
|
||||
return {"plan_id": plan_id, "status": "success"}
|
||||
|
||||
@router.put("/{plan_id}", response_model=dict)
|
||||
def edit_production_plan(plan_id: int, plan: PlanSchema):
|
||||
plan_data = plan.dict()
|
||||
assigned_machine_ids = plan.equipment_ids
|
||||
start_date_str = plan.start_date
|
||||
required_days = plan.production_days
|
||||
|
||||
works_on_saturday = plan.works_on_saturday
|
||||
works_on_sunday = plan.works_on_sunday
|
||||
|
||||
end_date_str = calculate_end_date(start_date_str, required_days, works_on_saturday, works_on_sunday)
|
||||
plan_data["end_date"] = end_date_str
|
||||
|
||||
success = update_production_plan(plan_id, plan_data, assigned_machine_ids)
|
||||
if not success:
|
||||
raise HTTPException(status_code=500, detail="Failed to update production plan")
|
||||
return {"status": "success"}
|
||||
|
||||
@router.delete("/{plan_id}", response_model=dict)
|
||||
def delete_plan(plan_id: int):
|
||||
success = delete_production_plan(plan_id)
|
||||
if not success:
|
||||
raise HTTPException(status_code=500, detail="Failed to delete production plan")
|
||||
return {"status": "success"}
|
||||
|
||||
@router.get("/", response_model=List[dict])
|
||||
def list_production_plans():
|
||||
return get_all_production_plans()
|
||||
|
||||
@router.get("/find-available-equipment", response_model=List[dict])
|
||||
def get_available_equipment(start_date: str, end_date: str, works_on_saturday: bool = False, works_on_sunday: bool = False):
|
||||
return find_available_equipment(start_date, end_date, works_on_saturday, works_on_sunday)
|
||||
|
||||
@router.put("/{plan_id}/assignments", response_model=dict)
|
||||
def update_assignment(plan_id: int, payload: AssignmentUpdatePayload):
|
||||
success = update_plan_assignment(plan_id, payload.dict())
|
||||
if not success:
|
||||
raise HTTPException(status_code=500, detail="Failed to update assignment")
|
||||
return {"status": "success"}
|
||||
|
||||
@router.post("/{plan_id}/assignments/redistribute", response_model=dict)
|
||||
def redistribute_assignments(plan_id: int, payload: RedistributionPayload):
|
||||
success = adjust_and_distribute_assignments(plan_id, payload.source_assignment, payload.distribution)
|
||||
if not success:
|
||||
raise HTTPException(status_code=500, detail="Failed to redistribute assignments")
|
||||
return {"status": "success"}
|
||||
Reference in New Issue
Block a user