Files
Aislo/M02_MasterTemplete/M02_MasterTemplete_Sangeun_Pick.ts
T
eomsangdonandClaude Opus 5.5 0e24c7a2aa feat(721-2): M02 찾아 넣기 창 — 탭 M01 전체(로직 · 인력 · 재료) · 단가산출 · 일위대가 · 찾기 칸 하나 · 거름 값 = 구분 · 출처 열
- 새 파일 M02_MasterTemplete_Find_Pick.ts — 있는 길 넷 이음(기준 목록 · 로직 · 층 서고 목록 · /logic-lib/pick 인력 job · 재료 price 서버 찾기) · 기계 · 실무 호표 뺌
- 부르는 곳 셋: 단가산출 [기본 로직 선택](로직 줄만) · [항목 추가](더한줄 인력 · 재료 = 요소 키 LB · MT 수량 1) · 일위대가 [로직 추가](Labor_Pick 이 lib.sangeun 이면 새 창)
- 일위대가 인력 · 재료 = 고정 줄 이음 꼴 fixedOf · lib.fixed 받는 칸은 723(sub1) — 그 전엔 회색 막힘
- 옛 창(B09 둘 · 불러오기 둘 · 프로젝트 층) 그대로 · 옛 창의 단가산출 탭 코드 걷음(부르는 곳 없음)
- 부품 상자: 데이터 표 흐린 줄 is-dim 더함
- 낡은 시험 test_717_4_sangeun_pick: 옛 창 단가산출 탭 · 재료 숨은 한 줄 글 대조 → 새 창 꼴로 고침
- 새 지킴 시험 test_721_find_pick(부르는 곳 · 옛 창 그대로 · 인력 · 재료 줄이 서버 셈에서 노임 · 자재 값)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 21:45:11 +09:00

90 lines
3.9 KiB
TypeScript

/* =============================================================================
* M02_MasterTemplete_Sangeun_Pick.ts
* M02 단가산출(SK) 고르기(PLAN 717-4) — 위 층 SK 목록 한 벌 · 단가산출 더한줄 고르기.
* · `listLayerDocs` = 층 목록 길(`/layers/{층}/templates` · 종류 하나)을 마스터 › 회사 › 개인 차례로 이음 ·
* 금액 = 서버가 붙인 1 단위 `기준금액` · `listSangeun` = 종류 `sangeun` · 찾아 넣기 창(`Find_Pick`) 탭 · B09 재료 창고 출처가 씀
* · 고른 SK = 참조 `{층, 주인, 키: SK-…}` — 일위대가 줄은 옛 참조 줄 꼴(서버 `M02_Labor_Expand` 가 펼침)
* · `openSangeunLinePicker` = 단가산출 [항목 추가] — 찾아 넣기 창(721-2 · M01 로직 · 인력 · 재료 · 단가산출 · 일위대가)
* → SK 문서 `더한줄` 한 줄(PLAN 715 이음 꼴 · 인력 · 재료 = 요소 키 LB · MT · 수량 1)
* ========================================================================== */
import { call, type Layer } from "./M02_MasterTemplete_Api_Fetch";
import { openFindPicker } from "./M02_MasterTemplete_Find_Pick";
import type { LaborRef } from "./M02_MasterTemplete_Labor_Calc";
export const SANGEUN_KIND = "sangeun";
/** 층 차례 — 위에서 아래 */
export const LAYER_ORDER = ["system", "company", "personal"] as const;
/** SK 목록 한 줄 */
export interface SangeunRow {
ref: LaborRef;
이름: string;
제목: string | null;
단위: string | null;
구분: string | null;
상세구분: string | null;
기준금액: number | null;
}
interface ListRow {
종류: string;
이름: string;
제목?: string | null;
단위?: string | null;
구분?: string | null;
상세구분?: string | null;
기준금액?: number | null;
}
/** 위 층 SK — 층 차례(마스터 › 회사 › 개인) · 층 안은 서버 차례 */
export const listSangeun = (scopes: Omit<LaborRef, "키">[]): Promise<SangeunRow[]> =>
listLayerDocs(scopes, SANGEUN_KIND);
/** 위 층 서고 문서 한 종류(sangeun · precombo) — 층 차례 · 층 안은 서버 차례 */
export async function listLayerDocs(
scopes: Omit<LaborRef, "키">[],
kind: string,
): Promise<SangeunRow[]> {
const rank = (x: Omit<LaborRef, "키">): number =>
LAYER_ORDER.indexOf(x.층 as (typeof LAYER_ORDER)[number]);
const sorted = [...scopes].sort((a, b) => rank(a) - rank(b));
const lists = await Promise.all(
sorted.map(async (at) => {
const q = at.주인 && at.층 !== "system" ? `?owner=${encodeURIComponent(at.주인)}` : "";
const got = await call<{ 양식: ListRow[] }>(`/layers/${at.층}/templates${q}`);
return got.양식
.filter((r) => r.종류 === kind)
.map<SangeunRow>((r) => ({
ref: { 층: at.층, 주인: at.층 === "system" ? null : at.주인, 키: r.이름 },
이름: r.이름,
제목: r.제목 ?? null,
단위: r.단위 ?? null,
구분: r.구분 ?? null,
상세구분: r.상세구분 ?? null,
기준금액: r.기준금액 ?? null,
}));
}),
);
return lists.flat();
}
/** 단가산출 더한줄 한 줄(PLAN 715 이음 꼴) */
export type SangeunLine =
| { 종류: "로직"; 로직: string; 입력값: Record<string, never>; 수량: number }
| { 참조: LaborRef; 수량: number }
| { 종류: "인력" | "재료"; 요소: string; 이름: string | null; 단위: string | null; 수량: number };
/** 단가산출 [항목 추가] — `scope` = 그 SK 문서 층(고를 수 있는 서고 = 위 층만) */
export function openSangeunLinePicker(
scope: { layer: Layer; owner: string | null },
done: (line: SangeunLine) => void,
): void {
openFindPicker({
...scope,
logic: (x) => done({ 종류: "로직", 로직: x.키, 입력값: {}, 수량: 1 }),
ref: (ref) => done({ 참조: ref, 수량: 1 }),
element: (e) => done({ 종류: e.종류, 요소: e.코드, 이름: e.이름, 단위: e.단위, 수량: 1 }),
});
}