ERP-node/frontend/lib/api/production.ts

179 lines
5.0 KiB
TypeScript
Raw Normal View History

/**
* API
*/
import apiClient from "./client";
// ─── 타입 정의 ───
export interface OrderSummaryItem {
item_code: string;
item_name: string;
total_order_qty: number;
total_ship_qty: number;
total_balance_qty: number;
order_count: number;
earliest_due_date: string | null;
current_stock: number;
safety_stock: number;
existing_plan_qty: number;
in_progress_qty: number;
required_plan_qty: number;
orders: OrderDetail[];
}
export interface OrderDetail {
id: string;
order_no: string;
part_code: string;
part_name: string;
order_qty: number;
ship_qty: number;
balance_qty: number;
due_date: string | null;
status: string;
customer_name: string | null;
}
export interface StockShortageItem {
item_code: string;
item_name: string;
current_qty: number;
safety_qty: number;
shortage_qty: number;
recommended_qty: number;
last_in_date: string | null;
}
export interface ProductionPlan {
id: number;
company_code: string;
plan_no: string;
plan_date: string;
item_code: string;
item_name: string;
product_type: string;
plan_qty: number;
completed_qty: number;
progress_rate: number;
start_date: string;
end_date: string;
due_date: string | null;
equipment_id: number | null;
equipment_code: string | null;
equipment_name: string | null;
status: string;
priority: string | null;
order_no: string | null;
parent_plan_id: number | null;
remarks: string | null;
}
export interface GenerateScheduleRequest {
items: {
item_code: string;
item_name: string;
required_qty: number;
earliest_due_date: string;
hourly_capacity?: number;
daily_capacity?: number;
lead_time?: number;
}[];
options?: {
safety_lead_time?: number;
recalculate_unstarted?: boolean;
product_type?: string;
};
}
export interface GenerateScheduleResponse {
summary: {
total: number;
new_count: number;
kept_count: number;
deleted_count: number;
};
schedules: ProductionPlan[];
}
// ─── API 함수 ───
/** 수주 데이터 조회 (품목별 그룹핑) */
export async function getOrderSummary(params?: {
excludePlanned?: boolean;
itemCode?: string;
itemName?: string;
}) {
const queryParams = new URLSearchParams();
if (params?.excludePlanned) queryParams.set("excludePlanned", "true");
if (params?.itemCode) queryParams.set("itemCode", params.itemCode);
if (params?.itemName) queryParams.set("itemName", params.itemName);
const qs = queryParams.toString();
const url = `/api/production/order-summary${qs ? `?${qs}` : ""}`;
const response = await apiClient.get(url);
return response.data as { success: boolean; data: OrderSummaryItem[] };
}
/** 안전재고 부족분 조회 */
export async function getStockShortage() {
const response = await apiClient.get("/api/production/stock-shortage");
return response.data as { success: boolean; data: StockShortageItem[] };
}
/** 생산계획 상세 조회 */
export async function getPlanById(planId: number) {
const response = await apiClient.get(`/api/production/plan/${planId}`);
return response.data as { success: boolean; data: ProductionPlan };
}
/** 생산계획 수정 */
export async function updatePlan(planId: number, data: Partial<ProductionPlan>) {
const response = await apiClient.put(`/api/production/plan/${planId}`, data);
return response.data as { success: boolean; data: ProductionPlan };
}
/** 생산계획 삭제 */
export async function deletePlan(planId: number) {
const response = await apiClient.delete(`/api/production/plan/${planId}`);
return response.data as { success: boolean; message: string };
}
/** 자동 스케줄 생성 */
export async function generateSchedule(request: GenerateScheduleRequest) {
const response = await apiClient.post("/api/production/generate-schedule", request);
return response.data as { success: boolean; data: GenerateScheduleResponse };
}
/** 스케줄 병합 */
export async function mergeSchedules(scheduleIds: number[], productType?: string) {
const response = await apiClient.post("/api/production/merge-schedules", {
schedule_ids: scheduleIds,
product_type: productType || "완제품",
});
return response.data as { success: boolean; data: ProductionPlan };
}
/** 반제품 계획 자동 생성 */
export async function generateSemiSchedule(
planIds: number[],
options?: { considerStock?: boolean; excludeUsed?: boolean }
) {
const response = await apiClient.post("/api/production/generate-semi-schedule", {
plan_ids: planIds,
options: options || {},
});
return response.data as { success: boolean; data: { count: number; schedules: ProductionPlan[] } };
}
/** 스케줄 분할 */
export async function splitSchedule(planId: number, splitQty: number) {
const response = await apiClient.post(`/api/production/plan/${planId}/split`, {
split_qty: splitQty,
});
return response.data as {
success: boolean;
data: { original: { id: number; plan_qty: number }; split: ProductionPlan };
};
}