- 기계 보기 부품(A00_Common/line_stack_machine_sheet) — 836-1 제어 구역 그대로(기계 표 꼴 훅 sheet · 잠금 lock) + 기본 정보 · 손료 근거 접이 카드 + 비슷한 기계에서 시작 · 값 바꾸면 브라우저 계산기로 즉시 - 서버 POST /api/m02/machine-sheet(M02_MyMachine_Sheet) — 식 고름 + 식 문서 + 처음 줄 값 + 연결 기록 · 쓰기 없음 · 파이썬 bind ↔ TS bindDoc 짝 - 덮음 ↔ 기계 줄(common_util_machine_sheet) — 고침 없음 = 줄 바이트 같음 · 내 기계 바로 · 직접 자리 맞춤 - 내 기계 = M01 에 없는 기계만 — 화면 만들기 · 고치기에서 M01 과 같은 이름 · 규격 409(불러오기 자동 생성은 그대로) · [새 기계] · 고침 열림 - 옛 기계 양식 부품(ui_template_machine_form) 지움 — 쓰는 곳 0(부품 모음 견본 줄도 걷음) - 낡은 시험 test_821_3 test_stack_line_copy — 836-2 자동 따라옴(내 기계 고치면 SK 금액 따라감 · 갱신 할 것 없음)에 맞춤 - 지킴 시험 test_840_2 — M01 기계 655 대 박은 식 셈 = 요소 셈 · 줄 그대로 · 굴착기 덮음 · 내 기계 꼴 · M01 같은 이름 막음 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
198 lines
6.1 KiB
TypeScript
198 lines
6.1 KiB
TypeScript
/* =============================================================================
|
|
* 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 "../common_util/common_util_machine_sheet";
|
|
import type { DocRecord } from "../common_util/common_util_formula_doc_cache";
|
|
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<Costs> {
|
|
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<MyMachine, "시간당"> {
|
|
시간당: 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<Costs>;
|
|
}
|
|
|
|
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, string> = {}): 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, string> = {}): 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<MyMachineRow[]> =>
|
|
(await call<{ 줄: MyMachineRow[] }>(at(owner))).줄;
|
|
|
|
export const readMyMachine = (owner: string | null, k: string): Promise<MyMachineOne> =>
|
|
call(at(owner, key(k)));
|
|
|
|
export const createMyMachine = (
|
|
owner: string | null,
|
|
body: MyMachineBody,
|
|
base?: string,
|
|
): Promise<MyMachineOne> =>
|
|
call(at(owner), { method: "POST", body: JSON.stringify({ 줄: body, 본뜬: base ?? null }) });
|
|
|
|
export const updateMyMachine = (
|
|
owner: string | null,
|
|
k: string,
|
|
body: MyMachineBody,
|
|
): Promise<MyMachineOne> =>
|
|
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<MachineLists> | null = null;
|
|
/** 양식 고르기 목록 — 한 번 받아 둠 */
|
|
export const fetchMyMachineLists = (): Promise<MachineLists> =>
|
|
(lists ??= call<MachineLists>("/my-machine-lists").catch((e) => {
|
|
lists = null;
|
|
return Promise.reject(e);
|
|
}));
|
|
|
|
export const findSimilar = async (owner: string | null, q: string): Promise<SimilarRow[]> =>
|
|
(await call<{ rows: SimilarRow[] }>(look(owner, "my-machine-find", { q }))).rows;
|
|
|
|
export const listMyItems = async (owner: string | null): Promise<MyItem[]> =>
|
|
(await call<{ rows: MyItem[] }>(look(owner, "my-items"))).rows;
|
|
|
|
/** 단가산출 줄 기계 입력 글(줄 쌓기 `기계='개인 EQP…'`) */
|
|
export const machineArg = (no: string): string => `'${no}'`;
|
|
|
|
/** 내 기계 → 기계 고르기 한 줄(`M01Element` 꼴 · 줄 쌓기 = 로직 + 기계='개인 EQP…') */
|
|
export const mineElement = (
|
|
row: Pick<MyMachine, "키" | "원문번호" | "이름" | "규격">,
|
|
h: MyHourly,
|
|
): M01Element => ({
|
|
종류: "기계",
|
|
코드: row.키,
|
|
이름: row.이름,
|
|
규격: row.규격,
|
|
단위: "시간",
|
|
값: h.ok ? (h.계 ?? null) : null,
|
|
단가: { 노무비: h.노무비 ?? 0, 재료비: h.재료비 ?? 0, 경비: h.경비 ?? 0 },
|
|
로직: h.로직 ?? undefined,
|
|
원문번호: row.원문번호,
|
|
});
|
|
|
|
/** 기계 창 [확인](827-1) — 초안 몸 검사 · 셈 꼴 값 · 시간당(식 키) · 그 식 셈 기록(계산기 캐시) · 쓰기 없음 */
|
|
export interface DraftCheck {
|
|
줄: MyMachine;
|
|
셈값: Record<string, unknown>;
|
|
시간당: MyHourly;
|
|
연결: DocRecord;
|
|
}
|
|
export const checkDraft = (
|
|
owner: string | null,
|
|
body: MyMachineBody,
|
|
target: { 표지: string; 키?: string; 본뜬?: string },
|
|
): Promise<DraftCheck> =>
|
|
call(at(owner, "/draft"), {
|
|
method: "POST",
|
|
body: JSON.stringify({
|
|
줄: body,
|
|
표지: target.표지,
|
|
키: target.키 ?? null,
|
|
본뜬: target.본뜬 ?? null,
|
|
}),
|
|
});
|
|
|
|
/** M01 기계 줄 값 + 시간당(기계 창 목록 · 양식 · 60 까지) */
|
|
export interface MachineBrief {
|
|
키: string;
|
|
원문번호: string;
|
|
이름: string;
|
|
규격: string;
|
|
값: MachineValues;
|
|
시간당: MyHourly;
|
|
}
|
|
export const machineRows = async (keys: string[]): Promise<MachineBrief[]> =>
|
|
keys.length
|
|
? (
|
|
await call<{ rows: MachineBrief[] }>(
|
|
`/logic-lib/machine-rows?keys=${encodeURIComponent(keys.join(","))}`,
|
|
)
|
|
).rows
|
|
: [];
|