2026-03-18 14:42:47 +09:00
|
|
|
import { apiClient } from "./client";
|
|
|
|
|
|
|
|
|
|
export interface EnrichedOrder {
|
|
|
|
|
sourceId: string;
|
|
|
|
|
orderNo: string;
|
|
|
|
|
partCode: string;
|
|
|
|
|
partName: string;
|
|
|
|
|
partnerName: string;
|
|
|
|
|
dueDate: string;
|
|
|
|
|
orderQty: number;
|
|
|
|
|
shipQty: number;
|
|
|
|
|
balanceQty: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ExistingPlan {
|
|
|
|
|
id: number;
|
|
|
|
|
sourceId: string;
|
|
|
|
|
planQty: number;
|
|
|
|
|
planDate: string;
|
|
|
|
|
shipmentPlanNo: string;
|
|
|
|
|
status: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface AggregateResponse {
|
|
|
|
|
[partCode: string]: {
|
|
|
|
|
totalBalance: number;
|
|
|
|
|
totalPlanQty: number;
|
|
|
|
|
currentStock: number;
|
|
|
|
|
availableStock: number;
|
|
|
|
|
inProductionQty: number;
|
|
|
|
|
existingPlans: ExistingPlan[];
|
|
|
|
|
orders: EnrichedOrder[];
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface BatchSavePlan {
|
|
|
|
|
sourceId: string;
|
|
|
|
|
planQty: number;
|
2026-03-18 16:04:55 +09:00
|
|
|
planDate?: string;
|
2026-03-18 14:42:47 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ID만 전달 → 백엔드에서 소스 테이블 자동 감지 + JOIN
|
|
|
|
|
export async function getShippingPlanAggregate(ids: string[]) {
|
|
|
|
|
const res = await apiClient.get("/shipping-plan/aggregate", {
|
|
|
|
|
params: { ids: ids.join(",") },
|
|
|
|
|
});
|
|
|
|
|
return res.data as {
|
|
|
|
|
success: boolean;
|
|
|
|
|
data: AggregateResponse;
|
|
|
|
|
source: "master" | "detail";
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function batchSaveShippingPlans(
|
|
|
|
|
plans: BatchSavePlan[],
|
|
|
|
|
source?: string
|
|
|
|
|
) {
|
|
|
|
|
const res = await apiClient.post("/shipping-plan/batch", { plans, source });
|
|
|
|
|
return res.data as { success: boolean; message?: string; data?: any };
|
|
|
|
|
}
|
2026-03-19 15:08:31 +09:00
|
|
|
|
|
|
|
|
// 출하계획 목록 조회 (관리 화면용)
|
|
|
|
|
export interface ShipmentPlanListItem {
|
|
|
|
|
id: number;
|
|
|
|
|
plan_date: string;
|
|
|
|
|
plan_qty: string;
|
|
|
|
|
status: string;
|
|
|
|
|
memo: string | null;
|
|
|
|
|
shipment_plan_no: string | null;
|
|
|
|
|
created_date: string;
|
|
|
|
|
created_by: string;
|
|
|
|
|
detail_id: string | null;
|
|
|
|
|
sales_order_id: number | null;
|
|
|
|
|
remain_qty: string | null;
|
|
|
|
|
order_no: string;
|
|
|
|
|
part_code: string;
|
|
|
|
|
part_name: string;
|
|
|
|
|
spec: string;
|
|
|
|
|
material: string;
|
|
|
|
|
customer_name: string;
|
|
|
|
|
partner_code: string;
|
|
|
|
|
due_date: string;
|
|
|
|
|
order_qty: string;
|
|
|
|
|
shipped_qty: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ShipmentPlanListParams {
|
|
|
|
|
dateFrom?: string;
|
|
|
|
|
dateTo?: string;
|
|
|
|
|
status?: string;
|
|
|
|
|
customer?: string;
|
|
|
|
|
keyword?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function getShipmentPlanList(params: ShipmentPlanListParams) {
|
|
|
|
|
const res = await apiClient.get("/shipping-plan/list", { params });
|
|
|
|
|
return res.data as { success: boolean; data: ShipmentPlanListItem[] };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 출하계획 단건 수정
|
|
|
|
|
export async function updateShipmentPlan(
|
|
|
|
|
id: number,
|
|
|
|
|
data: { planQty?: number; planDate?: string; memo?: string }
|
|
|
|
|
) {
|
|
|
|
|
const res = await apiClient.put(`/shipping-plan/${id}`, data);
|
|
|
|
|
return res.data as { success: boolean; data?: any; message?: string };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── 출하지시 API ───
|
|
|
|
|
|
|
|
|
|
export async function getShippingOrderList(params?: {
|
|
|
|
|
dateFrom?: string;
|
|
|
|
|
dateTo?: string;
|
|
|
|
|
status?: string;
|
|
|
|
|
customer?: string;
|
|
|
|
|
keyword?: string;
|
|
|
|
|
}) {
|
|
|
|
|
const res = await apiClient.get("/shipping-order/list", { params });
|
|
|
|
|
return res.data as { success: boolean; data: any[] };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function saveShippingOrder(data: any) {
|
|
|
|
|
const res = await apiClient.post("/shipping-order/save", data);
|
|
|
|
|
return res.data as { success: boolean; data?: any; message?: string };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function previewShippingOrderNo() {
|
|
|
|
|
const res = await apiClient.get("/shipping-order/preview-no");
|
|
|
|
|
return res.data as { success: boolean; instructionNo: string };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function deleteShippingOrders(ids: number[]) {
|
|
|
|
|
const res = await apiClient.post("/shipping-order/delete", { ids });
|
|
|
|
|
return res.data as { success: boolean; deletedCount?: number; message?: string };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 모달 데이터 소스 (페이징 지원)
|
|
|
|
|
export interface PaginatedSourceResponse {
|
|
|
|
|
success: boolean;
|
|
|
|
|
data: any[];
|
|
|
|
|
totalCount: number;
|
|
|
|
|
page: number;
|
|
|
|
|
pageSize: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function getShipmentPlanSource(params?: { keyword?: string; customer?: string; page?: number; pageSize?: number }) {
|
|
|
|
|
const res = await apiClient.get("/shipping-order/source/shipment-plan", { params });
|
|
|
|
|
return res.data as PaginatedSourceResponse;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function getSalesOrderSource(params?: { keyword?: string; customer?: string; page?: number; pageSize?: number }) {
|
|
|
|
|
const res = await apiClient.get("/shipping-order/source/sales-order", { params });
|
|
|
|
|
return res.data as PaginatedSourceResponse;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function getItemSource(params?: { keyword?: string; page?: number; pageSize?: number }) {
|
|
|
|
|
const res = await apiClient.get("/shipping-order/source/item", { params });
|
|
|
|
|
return res.data as PaginatedSourceResponse;
|
|
|
|
|
}
|