Merge remote-tracking branch 'origin/sub_laptop_6' into main_laptop_1
This commit is contained in:
@@ -2,7 +2,8 @@
|
||||
* M02_DF_Standards.ts
|
||||
* 단가산출 흐름도 — 단위 · 금액 표준 표(정함 11 · 12)
|
||||
* 처음 값 = `_standard/단위표준.json` · `금액단위표준.json`(산림품셈 1-2-2 · 원문 흠 그대로 — 사용자가 고침)
|
||||
* 서버 = `GET · PUT · DELETE /api/m02/df/standards` → {unit, money, saved} · 고친 것은 `_data`(마스터에 안 씀)
|
||||
* 서버 = `M02_DF_Api` cfStandards · cfStandardsSave · cfStandardsReset(`/api/m02/df/standards`) → {unit, money, saved} ·
|
||||
* 고친 것은 `_data`(마스터에 안 씀)
|
||||
* `renderStandards(host, on)` = 시험판 안 「표준 표」 판(두 표 보기 · 칸 고치기 · 저장 · 처음 값으로)
|
||||
* `standardsList()` = 단위 고르기 · 끝수 제안이 부르는 목록(동기 · 처음엔 번들 값 · 판이 서버 값을 받으면 그것)
|
||||
* 이 폴더째 지워도 됨.
|
||||
@@ -10,7 +11,7 @@
|
||||
|
||||
import { currentLanguageIndex } from "@ui/ui_template_locale";
|
||||
import { createButton, el, showConfirmDialog, showToast } from "@ui/ui_template_elements";
|
||||
import { API_BASE_URL } from "@config/config_frontend";
|
||||
import { cfStandards, cfStandardsReset, cfStandardsSave, type CfStandards } from "./M02_DF_Api";
|
||||
import unitDefault from "./_standard/단위표준.json";
|
||||
import moneyDefault from "./_standard/금액단위표준.json";
|
||||
import "./M02_DF_Standards.css";
|
||||
@@ -148,21 +149,12 @@ export const standardsNow = (): Standards => clone(current);
|
||||
|
||||
/* ── 서버 ─────────────────────────────────────────────────────────────── */
|
||||
|
||||
async function call(method: "GET" | "PUT" | "DELETE", body?: unknown): Promise<Standards> {
|
||||
const response = await fetch(`${API_BASE_URL}/m02/df/standards`, {
|
||||
method,
|
||||
credentials: "include",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: body === undefined ? undefined : JSON.stringify(body),
|
||||
});
|
||||
const data = (await response.json().catch(() => ({}))) as Standards & { detail?: unknown };
|
||||
if (!response.ok) throw new Error(String(data.detail ?? response.statusText));
|
||||
return data;
|
||||
}
|
||||
/** 서버 답(`M02_DF_Api` CfStandards) → 이 판의 모양 */
|
||||
const asStd = (v: CfStandards): Standards => v as unknown as Standards;
|
||||
|
||||
/** 서버 표 받기 — 못 받으면 처음 값 */
|
||||
export async function loadStandards(): Promise<Standards> {
|
||||
current = await call("GET");
|
||||
current = asStd(await cfStandards());
|
||||
return clone(current);
|
||||
}
|
||||
|
||||
@@ -311,7 +303,14 @@ export function renderStandards(host: HTMLElement, on: StandardsOn = {}): void {
|
||||
async function doSave(): Promise<void> {
|
||||
save.disabled = true;
|
||||
try {
|
||||
take(await call("PUT", { unit: work.unit, money: work.money }));
|
||||
take(
|
||||
asStd(
|
||||
await cfStandardsSave({ unit: work.unit, money: work.money } as unknown as Omit<
|
||||
CfStandards,
|
||||
"saved"
|
||||
>),
|
||||
),
|
||||
);
|
||||
showToast(tx("Saved"), "success");
|
||||
} catch {
|
||||
showToast(tx("SaveFailed"), "error");
|
||||
@@ -322,7 +321,7 @@ export function renderStandards(host: HTMLElement, on: StandardsOn = {}): void {
|
||||
async function doReset(): Promise<void> {
|
||||
if (!(await showConfirmDialog(tx("ResetAsk"), tx("Reset")))) return;
|
||||
try {
|
||||
take(await call("DELETE"));
|
||||
take(asStd(await cfStandardsReset()));
|
||||
} catch {
|
||||
take(clone(ORIGINAL)); // 서버가 없으면 화면만 처음 값
|
||||
}
|
||||
|
||||
@@ -337,18 +337,15 @@ def _run(lg: dict, master, examples: dict | None = None) -> dict:
|
||||
|
||||
|
||||
def test_값_메쌓기_value_는_calc_와_같음(master) -> None:
|
||||
from M01_MasterData.LogicBuilder import M01_LB_Calc as lb
|
||||
from M01_MasterData import M01_MasterData_Store as store
|
||||
|
||||
_, files = master
|
||||
rows = {r["키"]: r for d in files.values() if d.get("그룹") == "로직" for r in d["줄"]}
|
||||
raw = lambda k: json.loads(json.dumps(rows[k], default=_plain)) # noqa: E731
|
||||
given = {v["name"]: v["example"] for v in SAMPLES["masonry"]["boxes"][0]["input"]["variables"]}
|
||||
want = lb.calc(raw("GF000219"), {**given, "초과증가율": 80}, {})
|
||||
want = store.calc("GF000219", {**given, "초과증가율": 80})
|
||||
assert abs(_run(SAMPLES["masonry"], master)["노무비"] - float(want["sums"]["계"])) < 1
|
||||
given = {v["name"]: v["example"] for v in SAMPLES["value"]["boxes"][0]["input"]["variables"]}
|
||||
given["qt"] = given.pop("q")
|
||||
assert _run(SAMPLES["value"], master)["시간당 작업량"] == float(
|
||||
lb.calc(raw("GF000133"), given, {})["result"]
|
||||
store.calc("GF000133", given)["result"]
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -143,3 +143,15 @@ def test_standardsList_목록() -> None:
|
||||
(1, 0, "버림"),
|
||||
(0.1, 1, "버림"),
|
||||
]
|
||||
|
||||
|
||||
def test_서버_표준_답이_처음_값과_같음() -> None:
|
||||
"""서버(`M02_DF_Values.standards`) 답 = `_standard` 처음 값 · 그 답으로 만든 목록 = 번들 처음 값 목록"""
|
||||
from M02_MasterTemplete.DataFlow import M02_DF_Values as dv
|
||||
|
||||
mine = STD.parent / "_data" / "시험-없는-폴더" # 만들지 않음 — 고친 것 없음 → 처음 값
|
||||
assert not mine.exists()
|
||||
got = dv.standards(STD, mine)
|
||||
assert got == {"unit": UNIT, "money": MONEY, "saved": False}
|
||||
server = _node(f"out(S.standardsList({json.dumps(got, ensure_ascii=False)}));")
|
||||
assert server == _node("out(S.standardsList());")
|
||||
|
||||
Reference in New Issue
Block a user