feat(M01): 몫 줄 단가 = 단가 x 몫 비율 · 줄 모달 윗줄 요소조각 · 로직 알약이 그 로직을 엶 (PLAN 5장)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WRFJmmhPi4exAzHgPZHMT
This commit is contained in:
@@ -26,6 +26,7 @@ import {
|
||||
openMaterialModal,
|
||||
openNoteModal,
|
||||
openRefModal,
|
||||
openLogic,
|
||||
openTableModal,
|
||||
type PickCond,
|
||||
} from "./M01_MasterData_UI_LogicLab_Modal";
|
||||
@@ -47,7 +48,7 @@ function toFragments(pieces: TextPiece[], ctx: DetailContext): Fragment[] {
|
||||
openTableModal({ title: piece.글, table: ref.키, row: ref.행, col: ref.열 });
|
||||
else if (piece.kind === "요소")
|
||||
openRefModal({ title: piece.글, ref: ref.키, prices: ctx.prices });
|
||||
else openNoteModal(piece.글, `${tl("Modal_Logic")} · ${ref.키}`);
|
||||
else openLogic(ref.키);
|
||||
};
|
||||
return { pill: { label: piece.글, onClick: open }, ...dim };
|
||||
});
|
||||
@@ -93,7 +94,10 @@ interface Entry {
|
||||
amount: number | null;
|
||||
/** 덧줄이면 true */
|
||||
extra: boolean;
|
||||
open: () => void;
|
||||
open: (self: Entry) => void;
|
||||
/** 서버 조각으로 그린 단가 자리 · 수량 풀이 — 줄 모달이 씀(붙기 전엔 없음) */
|
||||
unitFrag?: Fragment[];
|
||||
piecesFrag?: Fragment[];
|
||||
}
|
||||
|
||||
/** 재료 고르기 줄 — `요소` 가 글 대신 {구분·상세구분·규격·대표} 객체 */
|
||||
@@ -194,7 +198,15 @@ const spread = (e: Entry, line?: CalcLine): Entry[] => {
|
||||
...e,
|
||||
group: OF_COST[k] ?? "other",
|
||||
amount: v,
|
||||
...(parts.length > 1 ? { share: k } : {}),
|
||||
...(parts.length > 1
|
||||
? {
|
||||
share: k,
|
||||
// 몫 줄 단가 = 단가 × (몫 금액 ÷ 줄 금액) — 곱하기 수량이 몫 금액과 맞게
|
||||
...(line && line.금액 && line.단가 != null
|
||||
? { price: formatMoney((line.단가 * v) / line.금액) }
|
||||
: {}),
|
||||
}
|
||||
: {}),
|
||||
}));
|
||||
};
|
||||
|
||||
@@ -217,8 +229,10 @@ function entries(ctx: DetailContext): Entry[] {
|
||||
price: price === undefined || price === null ? "" : formatMoney(price),
|
||||
amount: line ? line.금액 : null,
|
||||
extra: false,
|
||||
open: () =>
|
||||
open: (self) =>
|
||||
openMaterialModal({
|
||||
unitFrag: self.unitFrag,
|
||||
qtyFrag: self.piecesFrag,
|
||||
title: item.이름 ?? (cond ? condLabel(cond) : item.요소),
|
||||
expr: item.수량,
|
||||
...(cond ? { cond, unit: item.단위 } : { element: item.요소 }),
|
||||
@@ -242,8 +256,10 @@ function entries(ctx: DetailContext): Entry[] {
|
||||
price: "",
|
||||
amount: line ? line.금액 : null,
|
||||
extra: true,
|
||||
open: () =>
|
||||
open: (self) =>
|
||||
openMaterialModal({
|
||||
unitFrag: self.unitFrag,
|
||||
qtyFrag: self.piecesFrag,
|
||||
title: extra.이름,
|
||||
expr: extra.식,
|
||||
prices: ctx.prices,
|
||||
@@ -267,7 +283,9 @@ function attachPieces(all: Entry[], ctx: DetailContext): void {
|
||||
if (lines.length !== mine.length) continue;
|
||||
mine.forEach((e, i) => {
|
||||
const pieces = lines[i].조각;
|
||||
if (pieces?.length) e.qtyFrag = toFragments(pieces, ctx);
|
||||
if (pieces?.length) e.qtyFrag = e.piecesFrag = toFragments(pieces, ctx);
|
||||
const unit = lines[i].요소조각;
|
||||
if (unit?.length) e.unitFrag = toFragments(unit, ctx);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -300,8 +318,8 @@ function lineRow(e: Entry): HTMLElement {
|
||||
cellOf(e.amount === null ? "" : formatMoney(e.amount), "m01-logic__money"),
|
||||
],
|
||||
});
|
||||
tr.addEventListener("click", e.open);
|
||||
tr.addEventListener("keydown", (ev) => ev.key === "Enter" && e.open());
|
||||
tr.addEventListener("click", () => e.open(e));
|
||||
tr.addEventListener("keydown", (ev) => ev.key === "Enter" && e.open(e));
|
||||
return tr;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user