1fb438bdcb
- 공용 DateInput (YYYY-MM-DD 통일): text input + Popover Calendar, 숫자 8자리 자동 - 삽입. CompactDateRange / 다이얼로그 입고요청일 적용. - DataGrid 헤더 라벨 truncate + TableHead 패딩 축소(!px-1.5): 좁은 컬럼에서 라벨 겹침/잘림 해소. - 구매요청서관리 그리드 컬럼 너비 합리화 (총 ~300px 절감)로 품명까지 화면 안에 표시. - 구매요청서 수정모드: 선택 1건 시 [구매요청서수정] 분기 → getDetail 로 헤더/라인 채워 다이얼로그 오픈. 확정·품의서생성 가드. - 공급업체 옵션을 client_mng 기반 listVendorOptions 로 신설 (운영 supply_mng=0 / client_mng=8946, M-BOM vendor 매칭). - 주문유형 CommCodeSelect groupId 0000005 → 0000167 (계약구분). - 고객사 셀렉트 → CustomerSelect 공용 컴포넌트로 교체. - 그리드 delivery_request_date 점 형식 → YYYY-MM-DD 정규화. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
154 lines
4.8 KiB
TypeScript
154 lines
4.8 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 listVendors(): Promise<Array<{ code: string; label: string }>> {
|
|
const res = await apiClient.get("/sales/purchase-request/vendors");
|
|
return (res.data?.data ?? []) as Array<{ code: string; label: string }>;
|
|
},
|
|
|
|
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;
|
|
},
|
|
};
|