/* ============================================================================= * M02_MyMachine_Api.ts * M02 내 기계 · 내 품목 서버 호출(PLAN 821-3) — 개인 층만. * 내 기계 = `/layers/personal/my-machines`(821-1 · `M02_MyMachine_Router`) — 목록 · 하나 · 만들기 · 고치기 · 지우기 * 양식 목록 · 비슷한 기계 찾기 · 내 품목 = `M02_MyMachine_Look`(읽기만) * ========================================================================== */ import type { MachinePick, MachineValues } from "@ui/ui_template_machine_form"; import { call } from "./M02_MasterTemplete_Api_Fetch"; import type { M01Element } from "./M02_MasterTemplete_Find_Pick"; export type MachineHow = "바로" | "품셈" | "직접"; type Costs = Record<"노무비" | "재료비" | "경비", number>; /** 서버 시간당 셈 답 — ok 아님 = 까닭 */ export interface MyHourly extends Partial { ok: boolean; 계?: number; 로직?: string | null; 직접?: boolean; reason?: string; } /** 내 기계 줄(저장 꼴) */ export interface MyMachine { 키: string; 원문번호: string; 이름: string; 규격: string; 방식: MachineHow; 값: MachineValues; 시간당?: Costs; 비고?: string; 넣은날: string; 고친날: string; 본뜬?: string; } export interface MyMachineRow extends Omit { 시간당: MyHourly; 쓰는곳수: number; } export interface Use { 키: string; 이름: string; } export interface MyMachineOne { 줄: MyMachine; 시간당: MyHourly; 같은이름: { 키: string; 이름: string; 규격: string; 출처: string }[]; 쓰는곳?: Use[]; } /** 보내는 줄 — 방식 · 값 또는 시간당(직접) */ export interface MyMachineBody { 이름: string; 규격: string; 방식: MachineHow; 값?: MachineValues; 시간당?: Partial; } export interface MachineLists { fuels: MachinePick[]; jobs: MachinePick[]; power: number; hour: number; } export interface SimilarRow { 키: string; 원문번호?: string; 이름: string; 규격: string; 구분: string; 값?: MachineValues; 방식?: MachineHow; 시간당?: Costs; 출처: "개인" | "M01"; } export interface MyItem { 이름: string; 규격: string; 단위: string; 값: unknown; 쓰는곳: Use[]; } const at = (owner: string | null, tail = "", q: Record = {}): string => { const ask = new URLSearchParams({ ...q, ...(owner ? { owner } : {}) }).toString(); return `/layers/personal/my-machines${tail}${ask ? `?${ask}` : ""}`; }; const look = (owner: string | null, path: string, q: Record = {}): string => { const ask = new URLSearchParams({ ...q, ...(owner ? { owner } : {}) }).toString(); return `/layers/personal/${path}${ask ? `?${ask}` : ""}`; }; const key = (k: string): string => `/${encodeURIComponent(k)}`; export const listMyMachines = async (owner: string | null): Promise => (await call<{ 줄: MyMachineRow[] }>(at(owner))).줄; export const readMyMachine = (owner: string | null, k: string): Promise => call(at(owner, key(k))); export const createMyMachine = ( owner: string | null, body: MyMachineBody, base?: string, ): Promise => call(at(owner), { method: "POST", body: JSON.stringify({ 줄: body, 본뜬: base ?? null }) }); export const updateMyMachine = ( owner: string | null, k: string, body: MyMachineBody, ): Promise => call(at(owner, key(k)), { method: "PUT", body: JSON.stringify({ 줄: body }) }); export const deleteMyMachine = (owner: string | null, k: string): Promise<{ 쓰는곳: Use[] }> => call(at(owner, key(k)), { method: "DELETE" }); let lists: Promise | null = null; /** 양식 고르기 목록 — 한 번 받아 둠 */ export const fetchMyMachineLists = (): Promise => (lists ??= call("/my-machine-lists").catch((e) => { lists = null; return Promise.reject(e); })); export const findSimilar = async (owner: string | null, q: string): Promise => (await call<{ rows: SimilarRow[] }>(look(owner, "my-machine-find", { q }))).rows; export const listMyItems = async (owner: string | null): Promise => (await call<{ rows: MyItem[] }>(look(owner, "my-items"))).rows; /** 단가산출 줄 기계 입력 글(줄 쌓기 `기계='개인 EQP…'`) */ export const machineArg = (no: string): string => `'${no}'`; /** 내 기계 → 기계 고르기 한 줄(`M01Element` 꼴 · 줄 쌓기 = 로직 + 기계='개인 EQP…') */ export const mineElement = ( row: Pick, h: MyHourly, ): M01Element => ({ 종류: "기계", 코드: row.키, 이름: row.이름, 규격: row.규격, 단위: "시간", 값: h.ok ? (h.계 ?? null) : null, 단가: { 노무비: h.노무비 ?? 0, 재료비: h.재료비 ?? 0, 경비: h.경비 ?? 0 }, 로직: h.로직 ?? undefined, 원문번호: row.원문번호, });