Files
wace_rps/frontend/lib/api/salesPurchaseRequest.ts
T
hjjeong 75f4ca8127 영업관리 구매요청 2메뉴 액션 완성 + SmartSelect 키보드 네비
- sales_request_part DDL 추출(운영 11133)→RPS(11134) 마이그레이션
- 백엔드 6 엔드포인트: 프로젝트 자동채움/M-BOM 품목/저장/품의서생성/SSO
  · 품의서 결재상신 Amaranth SSO (target_type=PROPOSAL, formId=1163)
- 프론트 다이얼로그 2개 (구매요청서작성 / 품의서생성 확인)
  · 프로젝트 선택→주문유형·제품구분·국내외·고객사·유무상 자동 채움
  · 행추가 시 M-BOM 품번 셀렉트→품명/공급업체/단가 자동 셋팅
- 공용 SmartSelect: ↑↓·Enter·Esc·Home·End·PageUp·Down 키보드 네비
- 그리드 delivery_request_date . → - 형식 정규화

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 14:01:26 +09:00

149 lines
4.6 KiB
TypeScript

// ============================================================
// 영업관리 > 구매요청서관리 / 품의서관리 (wace_plm 1:1)
// 백엔드: /api/sales/purchase-request, /api/sales/purchase-proposal
// ============================================================
import { apiClient } from "./client";
export interface SalesPurchaseRequestFilter {
project_no?: string;
part_no?: string;
part_name?: string;
purchase_type?: string;
writer?: string;
part_type?: string;
search_status?: string;
proposal_no?: string;
regdate_start?: string;
regdate_end?: string;
page?: number;
page_size?: number;
}
export interface SalesPurchaseRequestListResponse<T = any> {
rows: T[];
totalCount: number;
page: number;
pageSize: number;
}
async function getList<T = any>(
path: string,
filter: SalesPurchaseRequestFilter,
): Promise<SalesPurchaseRequestListResponse<T>> {
const res = await apiClient.get(`/sales/${path}`, { params: filter });
return res.data?.data as SalesPurchaseRequestListResponse<T>;
}
export interface PurchaseRequestPartInput {
objid?: string;
part_objid: string;
part_name?: string;
qty?: string | number;
org_qty?: string | number;
partner_objid?: string;
partner_price?: string | number;
delivery_request_date?: string;
status?: string;
}
export interface SavePurchaseRequestPayload {
objid?: string;
project_no?: string;
mbom_header_objid?: string;
purchase_type?: string;
order_type?: string;
product_name?: string;
area_cd?: string;
customer_objid?: string;
paid_type?: string;
delivery_request_date?: string;
parts: PurchaseRequestPartInput[];
}
export interface MbomPartItem {
mbom_detail_objid: string;
part_objid: string;
mbom_header_objid: string;
part_no: string;
part_name: string;
unit: string;
qty: number;
unit_price: number;
vendor_objid: string;
vendor_name: string;
}
export interface ProjectAutoFillInfo {
objid: string;
project_no: string;
project_name: string;
category_cd: string | null;
category_name: string | null;
customer_objid: string | null;
customer_name: string | null;
product: string | null;
product_name: string | null;
area_cd: string | null;
area_name: string | null;
paid_type: string | null;
contract_objid: string | null;
mbom_header_objid: string | null;
}
export interface ProposalTargetPart {
objid: string;
part_objid: string;
part_no: string;
part_name: string;
qty: string;
unit_price: number;
total_price: number | null;
vendor_pm: string;
vendor_name: string;
}
export const salesPurchaseRequestApi = {
listPurchaseRequestReg: (f: SalesPurchaseRequestFilter = {}) => getList("purchase-request", f),
listPurchaseRegProposal: (f: SalesPurchaseRequestFilter = {}) => getList("purchase-proposal", f),
async getProjectAutoFill(projectObjid: string): Promise<ProjectAutoFillInfo | null> {
const res = await apiClient.get(`/sales/purchase-request/project-info/${projectObjid}`);
return (res.data?.data ?? null) as ProjectAutoFillInfo | null;
},
async listMbomParts(projectObjid: string): Promise<MbomPartItem[]> {
const res = await apiClient.get("/sales/purchase-request/mbom-parts", {
params: { project_objid: projectObjid },
});
return (res.data?.data ?? []) as MbomPartItem[];
},
async getDetail(objid: string): Promise<{ header: any; parts: any[] }> {
const res = await apiClient.get(`/sales/purchase-request/${objid}`);
return res.data?.data as { header: any; parts: any[] };
},
async getProposalTargets(objid: string): Promise<{ targets: ProposalTargetPart[]; excluded: ProposalTargetPart[] }> {
const res = await apiClient.get(`/sales/purchase-request/${objid}/proposal-targets`);
return res.data?.data as { targets: ProposalTargetPart[]; excluded: ProposalTargetPart[] };
},
async save(payload: SavePurchaseRequestPayload): Promise<{ objid: string; request_mng_no: string | null; isNew: boolean }> {
const res = await apiClient.post("/sales/purchase-request", payload);
return res.data?.data;
},
async createProposal(srmObjid: string): Promise<{ proposal_objid: string; proposal_no: string; part_count: number }> {
const res = await apiClient.post(`/sales/purchase-request/${srmObjid}/proposal`, {});
return res.data?.data;
},
async startApproval(proposalObjid: string, opts: { approvalTitle?: string; subjectStr?: string } = {}): Promise<{
fullUrl: string; approKey: string; status: string; proposalObjid: string;
}> {
const res = await apiClient.post(`/sales/purchase-proposal/${proposalObjid}/approval`, opts);
return res.data?.data;
},
};