feat(717-4): 일위대가 [로직 추가] 「단가산출」 탭 · B09 재료 창고 단가산출 출처 · 단가산출 더한줄 고르기

- 새 M02_MasterTemplete_Sangeun_Pick — listSangeun = 위 층 SK 목록(마스터 › 회사 › 개인 · 금액 = 층 목록 기준금액) · openSangeunLinePicker = SK 더한줄 고르기(M01 로직 · 일위대가 · 단가산출 · M01 재료 → 715 더한줄 꼴)
- Labor_Pick — lib.sangeun 이면 탭 [기준 목록 | 단가산출] · 단가산출 탭 = 기준 목록 표 꼴(출처 = 단가산출 · 층) · 줄 누름 = 참조 {층, 주인, SK 키}
- withHopyo(일위대가 [로직 추가]) 에 sangeun 켬 · B09 단가연결 창은 그대로(SK 공사 연결 = 719-1 뒤)
- B09 재료 창고 출처 탭 「단가산출」 — SK 목록 · 연결은 알림만
- locale_m2 키 넷 · 시험 test_717_4_sangeun_pick

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-01 16:06:31 +09:00
co-authored by Claude Opus 5.5
parent b9373d6c7f
commit 9d72d80b53
6 changed files with 290 additions and 13 deletions
+28 -2
View File
@@ -1,6 +1,7 @@
/* =============================================================================
* B09_Estimation_UI_Store.ts
* B09 설계내역서 오른쪽 재료 창고(PLAN 703-1) — 찾기 하나 + 출처 탭(이 공사 · 내 것 · 회사 · 품셈 · 지난 공사).
* B09 설계내역서 오른쪽 재료 창고(PLAN 703-1) — 찾기 하나 + 출처 탭(이 공사 · 내 것 · 회사 · 단가산출 · 품셈 · 지난 공사).
* 단가산출(717-4) = 위 층 M02 SK 목록(`Sangeun_Pick` · 마스터 › 회사 › 개인) · 공사 연결은 아직 없음(목록만)
*
* 두 번 누름 · Enter = 고른 내역 줄(`…_Bill_Level` 고름)에 단가연결 · 끌어 놓기 = 놓은 줄에 단가연결 ·
* 우클릭 = [고른 줄에 연결] · 품셈 = [계산서 보기](704-2 `Labor_Sheet` · [담기] = 연결)
@@ -31,17 +32,19 @@ import {
} from "../M02_MasterTemplete/M02_MasterTemplete_Labor_Api";
import { openStandardSheet } from "../M02_MasterTemplete/M02_MasterTemplete_Labor_Sheet";
import { ownOwner } from "../M02_MasterTemplete/M02_MasterTemplete_Layer";
import { listSangeun } from "../M02_MasterTemplete/M02_MasterTemplete_Sangeun_Pick";
import type { Row } from "./B09_Estimation_Calc_Base";
import type { TabContext } from "./B09_Estimation_UI_Tabs";
import { applyAt, openMenuAt } from "./B09_Estimation_UI_Tabs_Bill_Edit";
import { askInputs, importLib, type ApplyRef } from "./B09_Estimation_UI_Tabs_Bill_Link";
import { pickedKey } from "./B09_Estimation_UI_Tabs_Bill_Level";
type Source = "here" | "mine" | "company" | "poomsem" | "past";
type Source = "here" | "mine" | "company" | "sangeun" | "poomsem" | "past";
const SOURCES: Array<[Source, string]> = [
["here", "이 공사"],
["mine", "내 것"],
["company", "회사"],
["sangeun", "단가산출"],
["poomsem", "품셈"],
["past", "지난 공사"],
];
@@ -115,6 +118,28 @@ async function layerItems(layer: "personal" | "company"): Promise<Item[]> {
];
}
/** 단가산출(717-4) — 위 층 SK(마스터 › 회사 › 개인) · 공사 연결 길 없음 = 알림만 */
async function sangeunItems(): Promise<Item[]> {
const user = await fetchSessionUser().catch(() => null);
const own = (["company", "personal"] as const)
.map((층) => ({ 층, 주인: ownOwner(층, user) }))
.filter((x) => x.주인);
const layerText: Record<string, string> = { system: "마스터", company: "회사", personal: "개인" };
return (await listSangeun([{ 층: "system", 주인: null }, ...own])).map((r) => {
const name = r.제목 || r.이름;
const sub = [r.구분, r.상세구분].filter(Boolean).join(" ");
const money = r.기준금액 === null ? "" : `${Math.round(r.기준금액).toLocaleString("ko-KR")}원`;
return {
tag: `단가산출 · ${layerText[r.ref.층] ?? r.ref.층}`,
name,
sub: [sub, money].filter(Boolean).join(" · "),
unit: r.단위 ?? "",
hit: has(`단가산출 ${name} ${sub}`),
go: () => showToast("단가산출은 아직 공사에 바로 연결하지 않음 — 목록 보기만", "info"),
};
});
}
/** 넣을 값 창 — 대표 규격 = 계산서(704-2)가 셈에 쓴 입력 전부(목록 `바꿈` 은 기본과 다른 것만 ·
* 기본을 다르게 보는 칸이 빠짐 — 석축헐기 뒷길이 60 · 0) · 못 받으면 `바꿈` */
function askStandard(apply: ApplyRef, r: StandardRow): void {
@@ -200,6 +225,7 @@ async function pastItems(): Promise<Item[]> {
const LOAD: Record<Exclude<Source, "here">, () => Promise<Item[]>> = {
mine: () => layerItems("personal"),
company: () => layerItems("company"),
sangeun: sangeunItems,
poomsem: poomsemItems,
past: pastItems,
};