b38f5957f2
구매관리 (wace 1:1) - backend: services/purchaseService.ts (7 list + 옵션 3종) + controllers/purchaseController.ts + routes/purchaseRoutes.ts (/api/purchase 마운트) - frontend: lib/api/purchase.ts + 7 page.tsx (list/quote-request/proposal/inbound/inbound-by-item/inbound-by-date/project-status) - 영업관리 4메뉴 DataGrid 패턴 통일 — pageSizeOptions=[10,15,20,50,100], emptyMessage, showColumnSettings/summaryStats/onRefresh/onDownload/showChart - 마스터단독 데이터(sales_request_master, project_mgmt+mbom_detail) 노출, detail/part 누락 테이블 의존은 빈 그리드 + UI 발주관리 (purchase/order/page.tsx) - EDataTable → DataGrid 교체 + logicstudio 6종 props + 날짜/숫자 pre-format M-BOM PR-B3 — 구매리스트 생성 (wace createPurchaseListFromMBom.do 1:1) - mbomService.createSalesRequest + controller + route POST /api/production/mbom/sales-request - 단건 체크 + 1:1 강제 + R-YYYYMMDD-NNN 채번 + sales_request_master 단건 INSERT - production/mbom/page.tsx 에 [구매리스트 생성] 버튼 M-BOM PR-B5 — BOM 할당 (mBomEbomSelectPopup.do) - mbomService.searchAssignableEboms/assignBom + controller + routes - MbomAssignDialog 신규, MbomDetailDialog 통합 생산관리 4메뉴 라우트 (생산계획&실적, 소요량) - prodPlanResultService/Controller + productionPlanResultRoutes (planResult/mbomReq) - mbomRequirementService + 4 page.tsx (prod-plan-result, prod-plan-result-equip, raw-material-requirement, semi-product-requirement) - lib/api/prodPlanResult.ts Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
93 lines
3.0 KiB
TypeScript
93 lines
3.0 KiB
TypeScript
// ============================================================
|
|
// 구매관리 — 7개 메뉴 그리드 API.
|
|
// 백엔드: /api/purchase/{menu-path}, /api/purchase/options/{suppliers|users|projects}
|
|
// ============================================================
|
|
|
|
import { apiClient } from "./client";
|
|
|
|
export interface PurchaseListFilter {
|
|
year?: string;
|
|
customer_objid?: string;
|
|
customer_cd?: string;
|
|
project_no?: string;
|
|
part_no?: string;
|
|
part_name?: string;
|
|
part_spec?: string;
|
|
partner_objid?: string;
|
|
purchase_order_no?: string;
|
|
proposal_no?: string;
|
|
search_status?: string;
|
|
writer?: string;
|
|
request_user?: string;
|
|
purchase_type?: string;
|
|
part_type?: string;
|
|
product_cd?: string;
|
|
paid_type?: string;
|
|
mail_send_yn?: string;
|
|
delivery_status?: string;
|
|
close_status?: string;
|
|
sales_mng_user_id?: string;
|
|
regdate_start?: string;
|
|
regdate_end?: string;
|
|
receipt_date_start?: string;
|
|
receipt_date_end?: string;
|
|
delivery_start_date?: string;
|
|
delivery_end_date?: string;
|
|
reg_start_date?: string;
|
|
reg_end_date?: string;
|
|
page?: number;
|
|
page_size?: number;
|
|
}
|
|
|
|
export interface PurchaseListResponse<T = any> {
|
|
rows: T[];
|
|
totalCount: number;
|
|
page: number;
|
|
pageSize: number;
|
|
}
|
|
|
|
export interface OptionItem {
|
|
code: string;
|
|
label: string;
|
|
}
|
|
|
|
async function getList<T = any>(path: string, filter: PurchaseListFilter): Promise<PurchaseListResponse<T>> {
|
|
const res = await apiClient.get(`/purchase/${path}`, { params: filter });
|
|
return res.data?.data as PurchaseListResponse<T>;
|
|
}
|
|
|
|
export const purchaseApi = {
|
|
// 그리드 7종
|
|
listPurchaseRequest: (f: PurchaseListFilter = {}) => getList("purchase-request", f),
|
|
listQuotationRequest: (f: PurchaseListFilter = {}) => getList("quotation-request", f),
|
|
listProposal: (f: PurchaseListFilter = {}) => getList("proposal", f),
|
|
listInbound: (f: PurchaseListFilter = {}) => getList("inbound", f),
|
|
listInboundByItem: (f: PurchaseListFilter = {}) => getList("inbound-by-item", f),
|
|
listInboundByDate: (f: PurchaseListFilter = {}) => getList("inbound-by-date", f),
|
|
listProjectStatus: (f: PurchaseListFilter = {}) => getList("project-status", f),
|
|
|
|
// 공통 옵션
|
|
async listSuppliers(): Promise<OptionItem[]> {
|
|
const r = await apiClient.get("/purchase/options/suppliers");
|
|
return (r.data?.data ?? []) as OptionItem[];
|
|
},
|
|
async listUsers(): Promise<OptionItem[]> {
|
|
const r = await apiClient.get("/purchase/options/users");
|
|
return (r.data?.data ?? []) as OptionItem[];
|
|
},
|
|
async listProjects(): Promise<OptionItem[]> {
|
|
const r = await apiClient.get("/purchase/options/projects");
|
|
return (r.data?.data ?? []) as OptionItem[];
|
|
},
|
|
};
|
|
|
|
/** 년도 옵션 — wace 운영판 동일 (현재년도 ±4) */
|
|
export function getYearOptions(): OptionItem[] {
|
|
const y = new Date().getFullYear();
|
|
const out: OptionItem[] = [];
|
|
for (let i = y + 4; i >= y - 4; i--) {
|
|
out.push({ code: String(i), label: String(i) });
|
|
}
|
|
return out;
|
|
}
|