Merge commit 'f8e6d0d14' into sub_laptop_3
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
/* =============================================================================
|
||||
* common_util_machine_coef.ts
|
||||
* 기계 손료계수 · 시간당 경비 미리보기(PLAN 821-2 · 요구서 796 1 장) — 기계 양식 즉시 셈.
|
||||
*
|
||||
* ⚠ 짝: `resources/master_data/scripts/master_machine_coef.py` — 같은 셈 · 같은 차례
|
||||
* (거울 시험 `resources/tester/test_821_2_machine_coef.py`). 한쪽만 고치면 화면과 저장이 갈림.
|
||||
* 계수 = 건설품셈 공통 8-1-5(계수마다 정수 반올림 · 손료계수 = 합) · 미리보기 끝수 = 서버
|
||||
* 기계경비식(줄 0.1 원 아래 버림 · 잡품 = 버린 주연료 × % · 비목 합 원 미만 버림) · 정본은 서버 식.
|
||||
* ========================================================================== */
|
||||
|
||||
export const MACHINE_INPUTS = [
|
||||
"내용시간",
|
||||
"연간표준가동시간",
|
||||
"상각비율",
|
||||
"정비비율",
|
||||
"연간관리비율",
|
||||
] as const;
|
||||
export const MACHINE_COEFS = ["상각비계수", "정비비계수", "관리비계수", "손료계수"] as const;
|
||||
|
||||
export type MachineCoefs = Record<(typeof MACHINE_COEFS)[number], number>;
|
||||
|
||||
const E = 1e-6; // 끊는 경계 부동소수 흔들림 막음
|
||||
|
||||
const num = (v: unknown): number => (typeof v === "number" && Number.isFinite(v) ? v : 0);
|
||||
const halfUp = (x: number): number => Math.floor(x + 0.5 + E);
|
||||
/** 줄 금액 = 0.1 원 아래 버림(B09 끝수 줄 자리). */
|
||||
const tenth = (x: number): number => Math.floor(x * 10 + E) / 10;
|
||||
|
||||
/** (내용시간 · 연간표준가동시간 · 상각비율 · 정비비율 · 연간관리비율) → 계수 넷 · 못 셈 = null. */
|
||||
export function machineCoef(
|
||||
life: unknown,
|
||||
yearly: unknown,
|
||||
dep: unknown,
|
||||
rep: unknown,
|
||||
mgmt: unknown,
|
||||
): MachineCoefs | null {
|
||||
const [t, h, a, m, k] = [life, yearly, dep, rep, mgmt].map(num);
|
||||
if (t <= 0 || h <= 0) return null;
|
||||
const n = t / h;
|
||||
const s = halfUp((a / t) * 1e7);
|
||||
const j = halfUp((m / t) * 1e7);
|
||||
const g = halfUp(((k * (1.1 * n + 0.9)) / (2 * n) / h) * 1e7);
|
||||
return { 상각비계수: s, 정비비계수: j, 관리비계수: g, 손료계수: s + j + g };
|
||||
}
|
||||
|
||||
/** 값 묶음에서 품셈 입력 다섯이 다 수일 때만 계수 넷. */
|
||||
export function machineCoefOf(values: Record<string, unknown>): MachineCoefs | null {
|
||||
if (!MACHINE_INPUTS.every((k) => typeof values[k] === "number")) return null;
|
||||
return machineCoef(
|
||||
...(MACHINE_INPUTS.map((k) => values[k]) as [number, number, number, number, number]),
|
||||
);
|
||||
}
|
||||
|
||||
export interface MachineHourly {
|
||||
손료: number;
|
||||
주연료: number;
|
||||
잡품: number;
|
||||
전력: number;
|
||||
조종원: number;
|
||||
노무비: number;
|
||||
재료비: number;
|
||||
경비: number;
|
||||
계: number;
|
||||
}
|
||||
|
||||
/** 값 묶음 + 유가(원/ℓ) · 노임(원/일) · 전력(원/kWh) · 시간환산 → 시간당 줄 · 비목 · 계. */
|
||||
export function machineHourly(
|
||||
values: Record<string, unknown>,
|
||||
fuel: number,
|
||||
wage: number,
|
||||
power = 0,
|
||||
hour = 1 / 8,
|
||||
): MachineHourly {
|
||||
const loss = Math.floor((num(values["가격"]) * 1000 * num(values["손료계수"])) / 1e7 + E);
|
||||
const oil = tenth(num(values["주연료"]) * num(fuel));
|
||||
const misc = tenth((oil * num(values["잡재료율"])) / 100);
|
||||
const elec = tenth(num(values["전력"]) * num(power));
|
||||
const crew = tenth(num(values["조종원"]) * hour * num(wage));
|
||||
const labor = Math.floor(crew + E);
|
||||
const material = Math.floor(oil + misc + elec + E);
|
||||
return {
|
||||
손료: loss,
|
||||
주연료: oil,
|
||||
잡품: misc,
|
||||
전력: elec,
|
||||
조종원: crew,
|
||||
노무비: labor,
|
||||
재료비: material,
|
||||
경비: loss,
|
||||
계: labor + material + loss,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
"""기계 손료계수 · 시간당 경비 미리보기(PLAN 821-2 · 요구서 796 1 장).
|
||||
|
||||
⚠ 짝: `common_util/common_util_machine_coef.ts` — 같은 셈 · 같은 차례(거울 시험
|
||||
`resources/tester/test_821_2_machine_coef.py`). 한쪽만 고치면 화면과 저장이 갈림.
|
||||
|
||||
계수(건설품셈 공통 8-1-5 · 시간당 10^-7):
|
||||
상각비계수 = 상각비율 ÷ 내용시간 · 정비비계수 = 정비비율 ÷ 내용시간 ·
|
||||
관리비계수 = 연간관리비율 × 평균취득가격 비율 ÷ 연간표준가동시간 ·
|
||||
평균취득가격 비율 = (1.1 N + 0.9) ÷ 2N · N = 내용시간 ÷ 연간표준가동시간 ·
|
||||
계수마다 정수로 반올림 · 손료계수 = 셋의 합.
|
||||
미리보기 = 서버 기계경비식(GC000267 ~)을 기본 옵션(보정 없음)으로 부른 값과 같은 끝수 —
|
||||
손료 = 가격(천원) × 1000 × 손료계수 ÷ 10^7 원 미만 버림 · 줄 금액은 0.1 원 아래 버림 ·
|
||||
잡품 = 버린 주연료 금액 × 잡재료율 % · 비목 합은 원 미만 버림(B09 끝수 `master_cut.engine`).
|
||||
정본은 서버 식(`M02_Machine_Hourly`) — 이것은 화면 즉시 셈용.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
|
||||
INPUTS = ("내용시간", "연간표준가동시간", "상각비율", "정비비율", "연간관리비율")
|
||||
COEFS = ("상각비계수", "정비비계수", "관리비계수", "손료계수")
|
||||
_E = 1e-6 # 끊는 경계 부동소수 흔들림 막음
|
||||
|
||||
|
||||
def _num(v) -> float:
|
||||
return float(v) if isinstance(v, (int, float)) and not isinstance(v, bool) else 0.0
|
||||
|
||||
|
||||
def _half_up(x: float) -> int:
|
||||
return math.floor(x + 0.5 + _E)
|
||||
|
||||
|
||||
def _tenth(x: float) -> float:
|
||||
"""줄 금액 = 0.1 원 아래 버림(B09 끝수 줄 자리)."""
|
||||
return math.floor(x * 10 + _E) / 10
|
||||
|
||||
|
||||
def coef(life, yearly, dep, rep, mgmt) -> dict | None:
|
||||
"""(내용시간 · 연간표준가동시간 · 상각 · 정비 · 연간관리 비율) → 계수 넷 · 못 셈 = None."""
|
||||
life, yearly, dep, rep, mgmt = (_num(x) for x in (life, yearly, dep, rep, mgmt))
|
||||
if life <= 0 or yearly <= 0:
|
||||
return None
|
||||
n = life / yearly
|
||||
s = _half_up(dep / life * 1e7)
|
||||
j = _half_up(rep / life * 1e7)
|
||||
g = _half_up(mgmt * (1.1 * n + 0.9) / (2 * n) / yearly * 1e7)
|
||||
return {"상각비계수": s, "정비비계수": j, "관리비계수": g, "손료계수": s + j + g}
|
||||
|
||||
|
||||
def coef_of(values: dict) -> dict | None:
|
||||
"""값 묶음(기계 줄 `값`)에서 품셈 입력 다섯이 다 수일 때만 계수 넷."""
|
||||
if not all(isinstance(values.get(k), (int, float)) for k in INPUTS):
|
||||
return None
|
||||
return coef(*(values[k] for k in INPUTS))
|
||||
|
||||
|
||||
def preview(
|
||||
values: dict, fuel: float, wage: float, power: float = 0.0, hour: float = 1 / 8
|
||||
) -> dict:
|
||||
"""값 묶음 + 유가(원/ℓ) · 노임(원/일) · 전력(원/kWh) · 시간환산 → 시간당 줄 · 비목 · 계."""
|
||||
loss = math.floor(_num(values.get("가격")) * 1000 * _num(values.get("손료계수")) / 1e7 + _E)
|
||||
oil = _tenth(_num(values.get("주연료")) * _num(fuel))
|
||||
misc = _tenth(oil * _num(values.get("잡재료율")) / 100)
|
||||
elec = _tenth(_num(values.get("전력")) * _num(power))
|
||||
crew = _tenth(_num(values.get("조종원")) * hour * _num(wage))
|
||||
labor, material = math.floor(crew + _E), math.floor(oil + misc + elec + _E)
|
||||
return {
|
||||
"손료": loss,
|
||||
"주연료": oil,
|
||||
"잡품": misc,
|
||||
"전력": elec,
|
||||
"조종원": crew,
|
||||
"노무비": labor,
|
||||
"재료비": material,
|
||||
"경비": loss,
|
||||
"계": labor + material + loss,
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
"""PLAN 821-2 기계 계수 계산 짝 — 지킴 시험.
|
||||
|
||||
① 계수 전수 대조: M01 기계표에서 품셈 입력 다섯 · 계수 넷이 다 있는 줄 = 파이썬 계수 셈과 같음
|
||||
(다른 줄 = 원문 표 값 그대로인 점보드릴 2 줄만 · 원문 777 · 셈 777.8).
|
||||
② 파이썬 · TS 거울: 같은 입력 → 같은 계수 · 같은 시간당 미리보기.
|
||||
③ 미리보기 = 서버 기계경비식(`M02_Machine_Hourly.hourly`) 견본 스무 대 · 비목 셋 같음.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
sys.path.insert(0, str(ROOT))
|
||||
sys.path.insert(0, str(ROOT / "resources" / "master_data" / "scripts"))
|
||||
|
||||
import master_machine_coef as mc # noqa: E402
|
||||
|
||||
DATA = ROOT / "resources" / "master_data"
|
||||
TS = ROOT / "common_util" / "common_util_machine_coef.ts"
|
||||
# 원문 표 값 ≠ 식(정비비계수 0.7 ÷ 9,000 × 10^7 = 777.8 → 원문 777 · 계 2,515) — 식을 비틀지 않음
|
||||
ORIGINAL_ODD = {"EQ000347", "EQ000348"}
|
||||
SAMPLES = (
|
||||
"EQ000001 EQ000006 EQ000022 EQ000026 EQ000040 EQ000051 EQ000073 EQ000076 EQ000126 EQ000151 "
|
||||
"EQ000176 EQ000201 EQ000226 EQ000229 EQ000246 EQ000326 EQ000401 EQ000434 EQ000455 EQ000544"
|
||||
).split()
|
||||
|
||||
|
||||
def _load(name: str) -> list[dict]:
|
||||
return json.loads((DATA / name).read_text(encoding="utf-8"))["줄"]
|
||||
|
||||
|
||||
MACHINES = _load("기계.json")
|
||||
FUEL = {r["원문번호"]: r["값"] for r in _load("재료_유가전력.json")}
|
||||
WAGE = {r["원문번호"]: r["값"] for r in _load("인력.json")}
|
||||
|
||||
|
||||
def _full(row: dict) -> bool:
|
||||
v = row["값"]
|
||||
return all(isinstance(v.get(k), (int, float)) for k in (*mc.INPUTS, *mc.COEFS))
|
||||
|
||||
|
||||
def _prices(v: dict) -> tuple[float, float]:
|
||||
"""전국평균 유가 · 노임(직종 비면 기계경비식 조종원직종 첫 고르기 1048)."""
|
||||
return FUEL.get(f"{v.get('주연료종류')}:전국평균", 0), WAGE.get(
|
||||
str(v.get("조종원직종") or "1048"), 0
|
||||
)
|
||||
|
||||
|
||||
def test_coef_matches_master_table():
|
||||
rows = [r for r in MACHINES if _full(r)]
|
||||
assert len(rows) >= 590
|
||||
odd = {r["키"] for r in rows if mc.coef_of(r["값"]) != {k: r["값"][k] for k in mc.COEFS}}
|
||||
assert odd == ORIGINAL_ODD
|
||||
|
||||
|
||||
def test_coef_excavator_example():
|
||||
got = mc.coef(10000, 1250, 0.9, 0.7, 0.1)
|
||||
assert got == {"상각비계수": 900, "정비비계수": 700, "관리비계수": 485, "손료계수": 2085}
|
||||
assert mc.coef(0, 1250, 0.9, 0.7, 0.1) is None
|
||||
assert mc.coef_of({"내용시간": 10000}) is None
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
not (ROOT / "config" / "node_modules" / "typescript").is_dir(),
|
||||
reason="프론트엔드 의존성 미설치",
|
||||
)
|
||||
def test_ts_mirror(tmp_path):
|
||||
coef_cases = [[r["값"][k] for k in mc.INPUTS] for r in MACHINES if _full(r)]
|
||||
coef_cases += [[10000, 1250, 0.9, 0.7, 0.1], [0, 1, 1, 1, 1], [3600, 540, 0.9, 1.15, 0.1]]
|
||||
hour_cases = []
|
||||
for r in MACHINES:
|
||||
fuel, wage = _prices(r["값"])
|
||||
hour_cases.append([r["값"], fuel, wage, 114.4, 0.125])
|
||||
hour_cases.append(
|
||||
[
|
||||
{"가격": 2680, "손료계수": 5313, "주연료": 1.0, "잡재료율": 10, "전력": 3.73},
|
||||
2000,
|
||||
0,
|
||||
114.4,
|
||||
0.125,
|
||||
]
|
||||
)
|
||||
src = tmp_path / "in.json"
|
||||
src.write_text(
|
||||
json.dumps({"coef": coef_cases, "hour": hour_cases}, ensure_ascii=False), encoding="utf-8"
|
||||
)
|
||||
script = f"""
|
||||
const fs = require("fs");
|
||||
const ts = require({json.dumps(str(ROOT / "config" / "node_modules" / "typescript"))});
|
||||
const opt = {{ module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }};
|
||||
const src = fs.readFileSync({json.dumps(str(TS))}, "utf8");
|
||||
const js = ts.transpileModule(src, {{ compilerOptions: opt }}).outputText;
|
||||
const m = {{ exports: {{}} }};
|
||||
new Function("exports", "module", js)(m.exports, m);
|
||||
const inp = JSON.parse(fs.readFileSync({json.dumps(str(src))}, "utf8"));
|
||||
process.stdout.write(JSON.stringify({{
|
||||
coef: inp.coef.map((c) => m.exports.machineCoef(...c)),
|
||||
hour: inp.hour.map((h) => m.exports.machineHourly(...h)),
|
||||
}}));
|
||||
"""
|
||||
out = subprocess.run(
|
||||
["node", "-e", script], capture_output=True, text=True, encoding="utf-8", check=True
|
||||
)
|
||||
got = json.loads(out.stdout)
|
||||
want_coef = [mc.coef(*c) for c in coef_cases]
|
||||
want_hour = [mc.preview(*h) for h in hour_cases]
|
||||
assert got["coef"] == want_coef
|
||||
assert len(got["hour"]) == len(want_hour)
|
||||
for a, b in zip(got["hour"], want_hour):
|
||||
assert a == pytest.approx(b, abs=1e-9)
|
||||
|
||||
|
||||
def test_preview_equals_server_hourly():
|
||||
from M02_MasterTemplete import M02_Machine_Hourly as mh
|
||||
|
||||
rows = {r["키"]: r for r in MACHINES}
|
||||
for key in SAMPLES:
|
||||
h = mh.hourly(key)
|
||||
assert h["ok"], (key, h)
|
||||
v = rows[key]["값"]
|
||||
p = mc.preview(v, *_prices(v))
|
||||
assert (p["노무비"], p["재료비"], p["경비"], p["계"]) == (
|
||||
h["노무비"],
|
||||
h["재료비"],
|
||||
h["경비"],
|
||||
h["계"],
|
||||
), (key, h["로직"])
|
||||
@@ -489,6 +489,8 @@ ative-standard.js에 표준시장단가 원천(SilJukDat)과 내역 행(EstMainD
|
||||
- 남음: 구성비·요율 전환(CalcBase), 약어 표시(SName), 제비율 기준 문서 보기(원본 한글 파일).
|
||||
- [x] 수량산출서 검색·전체보기(원본 TFRMMULLANG btnSerch·btnAllDisplay — 빈칸·|·괄호 무시 포함 검색) — 고르기 줄을 `native-quantity-sheets.js` 로 옮겨 700줄 제한 유지.
|
||||
- 검증완료: `test_est_quantity_sheets.py` 검색 시험 포함 수량 시험 22개 통과. ORCA 브라우저에서 「집수」 검색 → 항목에 집수정이 있는 「배수」만·선택 이동, 전체보기 → 3개 복귀, 샘플 복구.
|
||||
- [x] 묶음 인쇄 간지 설정값 일괄적용·기본양식에저장·전체선택/선택해제(원본 TFRMESTPRINTPRIVATE btnGangiAllSet·btnSaveToMain, TFRMESTPRINT2 btnNoselect) — 간지 인쇄·간지 겹테두리를 모든 서식에 같게, 고른 서식·간지 설정을 「묶음기본양식」(양식 보관함 종류 print)으로 저장해 묶음 설정 없는 공사에서 열 때 씀.
|
||||
- 검증완료: 묶음 인쇄·바인딩 시험 통과. ORCA 브라우저에서 선택해제 0 · 전체선택 40, 겹테두리 끔 → 미리보기 간지 테두리 없음, 기본양식 저장 뒤 설정 지우고 다시 열면 1개·겹테두리 끔 복원, 양식 지우고 샘플 복구.
|
||||
- [x] 갑지 공사금액 자동변경(원본 TFRMGABGI popupCostChange) — 「공사금액 자동변경」 체크 시 고른 원가 비목·방식을 기억해 인쇄 때마다 현재 원가 금액으로 공사금액 글을 다시 만듦(다시 열면 고른 비목·방식 그대로).
|
||||
- 검증완료: 문서 시험 3개 통과. ORCA 브라우저에서 도급액 고정 풀고 자동변경 저장 → 수량 2배 뒤 인쇄 금액 「칠천구백육십만삼천삼백이십사원」→「팔천이백칠만사천팔백구십일원」, 저장 글은 그대로, 샘플 복구.
|
||||
- [x] 선택 행 예정공정표에 표시/해제(원본 mnuShowSchedule · popMainShowChart) — 내역서에서 고른 상세 행만 공정표에 넣음(이미 있는 행은 건너뜀), 고른 행이 모두 있으면 뺌(검증: 2행 넣기 → 다시 눌러 0행).
|
||||
|
||||
@@ -18,7 +18,7 @@ const EstPrintBatch = (() => {
|
||||
Name: row.Name2 || row.Name || String(row.Index),
|
||||
checked: saved ? saved.includes(row.Index) : Number(row.Checked) === 1,
|
||||
gangi: project.printBatch?.gangi ?? Number(row.PrintGangiShow) === 1,
|
||||
outline: Number(row.PrintGangiOutLineShow ?? 1) === 1,
|
||||
outline: project.printBatch?.outline ?? Number(row.PrintGangiOutLineShow ?? 1) === 1,
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -54,7 +54,21 @@ const EstPrintBatch = (() => {
|
||||
}
|
||||
|
||||
let catalog = [];
|
||||
// 간지 설정값 일괄적용(btnGangiAllSet): 간지 인쇄·겹테두리를 모든 서식에 같게. 기본양식에저장(btnSaveToMain):
|
||||
// 고른 서식·간지 설정을 서버 양식 보관함(종류 print, 이름 「묶음기본양식」)에 — 묶음 설정이 없는 공사에서 열 때 씀.
|
||||
const DEFAULT = "묶음기본양식";
|
||||
const post = (body) => ({
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
async function open(state) {
|
||||
if (!state.project.printBatch) {
|
||||
const saved = (await EstApp.api("/api/forms")).find(
|
||||
(f) => f.kind === "print" && f.name === DEFAULT,
|
||||
);
|
||||
if (saved) EstApp.change((project) => (project.printBatch = saved.data), false);
|
||||
}
|
||||
const defaults = await EstApp.api("/api/print-catalog");
|
||||
const original = new Map((state.project.printCatalog || []).map((row) => [row.Index, row]));
|
||||
catalog = defaults.map((row) => ({ ...row, ...original.get(row.Index) }));
|
||||
@@ -64,16 +78,17 @@ const EstPrintBatch = (() => {
|
||||
const list = forms(catalog, state.project);
|
||||
EstApp.showDialog(
|
||||
"묶음 인쇄(설계서 일체)",
|
||||
`<p>인쇄할 서식을 고르세요. 인쇄표 차례대로 이어 인쇄합니다.</p><label><input type="checkbox" name="pb-gangi" ${list[0]?.gangi ? "checked" : ""}>간지 인쇄</label><div style="max-height:260px;overflow:auto;columns:2">${list.map((f) => `<label style="display:block"><input type="checkbox" name="pb-form" value="${esc(f.Index)}" ${f.checked ? "checked" : ""}>${esc(f.Name)}</label>`).join("")}</div><button data-action="print-batch-preview">미리보기</button> <button data-action="print-batch-print">인쇄</button><p id="print-batch-note"></p><iframe id="print-batch-frame" style="width:100%;height:360px;border:1px solid #ccc"></iframe>`,
|
||||
`<p>인쇄할 서식을 고르세요. 인쇄표 차례대로 이어 인쇄합니다.</p><label><input type="checkbox" name="pb-gangi" ${list[0]?.gangi ? "checked" : ""}>간지 인쇄</label> <label><input type="checkbox" name="pb-outline" ${list[0]?.outline !== false ? "checked" : ""}>간지 겹테두리</label> (모든 서식에 일괄적용) <button data-action="print-batch-all">전체선택</button><button data-action="print-batch-none">선택해제</button><button data-action="print-batch-default">기본양식에저장</button><div style="max-height:260px;overflow:auto;columns:2">${list.map((f) => `<label style="display:block"><input type="checkbox" name="pb-form" value="${esc(f.Index)}" ${f.checked ? "checked" : ""}>${esc(f.Name)}</label>`).join("")}</div><button data-action="print-batch-preview">미리보기</button> <button data-action="print-batch-print">인쇄</button><p id="print-batch-note"></p><iframe id="print-batch-frame" style="width:100%;height:360px;border:1px solid #ccc"></iframe>`,
|
||||
);
|
||||
}
|
||||
function read(state) {
|
||||
const checked = [...document.querySelectorAll('#dialog-content [name="pb-form"]:checked')].map(
|
||||
(n) => (/^\d+$/.test(n.value) ? Number(n.value) : n.value),
|
||||
);
|
||||
const gangi = document.querySelector('#dialog-content [name="pb-gangi"]').checked;
|
||||
const gangi = document.querySelector('#dialog-content [name="pb-gangi"]').checked,
|
||||
outline = document.querySelector('#dialog-content [name="pb-outline"]').checked;
|
||||
if (!checked.length) throw Error("인쇄할 서식을 하나 이상 고르세요.");
|
||||
const next = { checked, gangi };
|
||||
const next = { checked, gangi, outline };
|
||||
if (JSON.stringify(next) !== JSON.stringify(state.project.printBatch))
|
||||
EstApp.change((project) => (project.printBatch = next), false);
|
||||
return next;
|
||||
@@ -96,7 +111,18 @@ const EstPrintBatch = (() => {
|
||||
EstApp.render();
|
||||
});
|
||||
else if (name === "print-batch-preview") build(state);
|
||||
else if (name === "print-batch-print") {
|
||||
else if (name === "print-batch-all" || name === "print-batch-none")
|
||||
for (const n of document.querySelectorAll('#dialog-content [name="pb-form"]'))
|
||||
n.checked = name === "print-batch-all";
|
||||
else if (name === "print-batch-default") {
|
||||
const data = read(state);
|
||||
EstApp.api("/api/forms", post({ kind: "print", name: DEFAULT, data }))
|
||||
.then(
|
||||
() =>
|
||||
(EstApp.byId("print-batch-note").textContent = "묶음 인쇄 기본양식을 저장했습니다."),
|
||||
)
|
||||
.catch((error) => (EstApp.byId("print-batch-note").textContent = error.message));
|
||||
} else if (name === "print-batch-print") {
|
||||
const frame = build(state);
|
||||
frame.onload = () => frame.contentWindow.print();
|
||||
} else return false;
|
||||
|
||||
Reference in New Issue
Block a user