fix(821-3): 줄 쌓기로 고른 내 기계 — 값 사본에 박음(고친 뒤 금액 그대로 + 새 값 · 갱신 · 지워짐) · 찾기 값 수로
- M02_Doc_Sk_Path.edited: 문서의 기계='개인 EQP…' 가운데 값 사본에 없는 것만 지금 값으로 더함(미리 셈 · 저장) - M02_MyMachine_Look.find: Decimal → 수(글이면 양식 미리보기 0) - 양식 막힘 글은 고치면 지움 · 좌측 칸 안내 짧게 - 시험 test_821_3 ⑤ 줄 쌓기 내 기계 사본 · 새값 · 갱신 · 지운 뒤 마지막 값 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,7 @@ from M02_MasterTemplete import M02_Doc_Import as dim
|
||||
from M02_MasterTemplete import M02_Doc_Screen as screen
|
||||
from M02_MasterTemplete import M02_Doc_Sk as dsk
|
||||
from M02_MasterTemplete import M02_MasterTemplete_Store as store
|
||||
from M02_MasterTemplete import M02_MyMachine as mym
|
||||
from M02_MasterTemplete import M02_Sangeun_Copy as skc
|
||||
from M02_MasterTemplete import M02_Sangeun_Doc as sd
|
||||
|
||||
@@ -128,11 +129,22 @@ def edited(copy: dict, body: dict, key: str, sk: dict | None = None) -> dict:
|
||||
*(c for d in out.get("끊음", {}).values() for c in dc.calls(d)),
|
||||
]
|
||||
if not dim.is_imported(sk):
|
||||
out |= _mine(out)
|
||||
out["부름"] = dc.closure(dc.over(out), calls, copy.get("부름"))
|
||||
out["따로"] = True
|
||||
return out
|
||||
|
||||
|
||||
def _mine(copy: dict) -> dict:
|
||||
"""줄 쌓기에서 고른 내 기계(기계='개인 EQP…') 가운데 값 사본에 없는 것만 지금 값으로 더함
|
||||
(821-3) — 그 뒤 내 기계를 고쳐도 금액 그대로 + 「단가새값」 · [단가 갱신] 으로 반영 ·
|
||||
지워도 마지막 값."""
|
||||
keys = mym.keys_in(copy.get("문서"))
|
||||
if not keys or "로직" not in copy:
|
||||
return {}
|
||||
return skc.grow(dc.values_of(copy), skc.snap([], keys))
|
||||
|
||||
|
||||
def preview(key: str, body: dict) -> dict[str, Any]:
|
||||
"""미리 셈(저장 없음) — {셈, 전, 후, 바뀐자원?, 버림?}."""
|
||||
doc = _file(key)["문서"]
|
||||
|
||||
@@ -158,36 +158,34 @@ export function buildSide(opt: SideOptions): SideHandle {
|
||||
});
|
||||
const sangeunSec = section(L("M02_SangeunTitle"), sangeun.body);
|
||||
// 내 기계 · 내 품목(821-3) — 자기 개인 층 · 펼치면 가운데 화면(목록 · 양식)
|
||||
const hint = (): HTMLElement => createEmpty({ text: mt("Own_Note"), small: true });
|
||||
const myMachSec = openOnExpand(section(mt("Title"), hint()), async () => {
|
||||
const hint = (key: "Side_Hint" | "Items_Side_Hint"): HTMLElement =>
|
||||
createEmpty({ text: mt(key), small: true });
|
||||
const myMachSec = openOnExpand(section(mt("Title"), hint("Side_Hint")), async () => {
|
||||
if (!(await opt.confirmLeave())) return;
|
||||
let mark = (_d: boolean): void => {};
|
||||
const node = buildMyMachineView({ owner: null, setDirty: (d) => mark(d) });
|
||||
mark = opt.showView(mt("Title"), node);
|
||||
});
|
||||
myMachSec.dataset.myMachines = "";
|
||||
const myItemsSec = openOnExpand(
|
||||
section(mt("Items_Title"), createEmpty({ text: mt("Items_Note"), small: true })),
|
||||
async () => {
|
||||
if (!(await opt.confirmLeave())) return;
|
||||
const node = buildMyItemsView({
|
||||
owner: null,
|
||||
openSk: async (u) => {
|
||||
if (!(await opt.confirmLeave())) return;
|
||||
opt.onOpen({
|
||||
layer: "personal",
|
||||
owner: null,
|
||||
canWrite: true,
|
||||
projectId: null,
|
||||
kind: "sangeun",
|
||||
name: u.키,
|
||||
label: `${u.키} ${u.이름}`.trim(),
|
||||
});
|
||||
},
|
||||
});
|
||||
opt.showView(mt("Items_Title"), node);
|
||||
},
|
||||
);
|
||||
const myItemsSec = openOnExpand(section(mt("Items_Title"), hint("Items_Side_Hint")), async () => {
|
||||
if (!(await opt.confirmLeave())) return;
|
||||
const node = buildMyItemsView({
|
||||
owner: null,
|
||||
openSk: async (u) => {
|
||||
if (!(await opt.confirmLeave())) return;
|
||||
opt.onOpen({
|
||||
layer: "personal",
|
||||
owner: null,
|
||||
canWrite: true,
|
||||
projectId: null,
|
||||
kind: "sangeun",
|
||||
name: u.키,
|
||||
label: `${u.키} ${u.이름}`.trim(),
|
||||
});
|
||||
},
|
||||
});
|
||||
opt.showView(mt("Items_Title"), node);
|
||||
});
|
||||
// 실무자료로 일위대가를 만들었음(확인 창 · 엑셀 보기 창) → 목록 다시 · 이 패널이 내려갔으면 듣기 끝
|
||||
const onBuilt = (): void =>
|
||||
precombo.body.isConnected
|
||||
|
||||
@@ -117,6 +117,7 @@ export async function mountMyMachineForm(
|
||||
checkSame();
|
||||
},
|
||||
onChange: () => {
|
||||
notice.replaceChildren(); // 지난 저장 막힘 글 지움(다시 [저장] 때 새로)
|
||||
opt.onDirty?.(dirty());
|
||||
checkSame();
|
||||
},
|
||||
|
||||
@@ -52,7 +52,7 @@ def find(q: str, limit: int = 30) -> list[dict]:
|
||||
]
|
||||
exact = (m01.loaded()[1].numbers.get("EQ") or {}).get(q.strip())
|
||||
head = [exact] if exact is not None and not mym.mine(exact.get("키")) else []
|
||||
m01_rows = [json.loads(json.dumps(r, default=float)) for r in head] + _m01m().find(q, limit)
|
||||
m01_rows = [*head, *_m01m().find(q, limit)]
|
||||
seen = set()
|
||||
for r in m01_rows:
|
||||
if r["키"] in seen:
|
||||
@@ -60,7 +60,7 @@ def find(q: str, limit: int = 30) -> list[dict]:
|
||||
seen.add(r["키"])
|
||||
brief = {k: r[k] for k in ("키", "원문번호", "이름", "규격", "값") if k in r}
|
||||
out.append({**brief, "구분": r.get("상세구분") or r.get("구분") or "", "출처": "M01"})
|
||||
return out[:limit]
|
||||
return json.loads(json.dumps(out[:limit], default=_m01m()._plain)) # Decimal → 수(글 아님)
|
||||
|
||||
|
||||
def _items_of(doc: dict) -> list[dict]:
|
||||
|
||||
@@ -38,6 +38,8 @@ const TEXT = {
|
||||
No_Uses: "쓰는 단가산출 없음",
|
||||
Leave_Ask: "저장 안 한 고침을 버리고 닫을까?",
|
||||
Mine: "내 기계",
|
||||
Side_Hint: "펼치면 가운데에 목록 · 양식",
|
||||
Items_Side_Hint: "펼치면 가운데에 모아 보기(읽기)",
|
||||
Won: "원",
|
||||
Labor: "노",
|
||||
Material: "재",
|
||||
|
||||
@@ -55,7 +55,7 @@ def test_find_mine_first_and_number(world):
|
||||
no = str(m01.loaded()[1].get(DIG)["원문번호"])
|
||||
first = _at(me, look.find, no)[0]
|
||||
assert first["키"] == DIG and first["원문번호"] == no and first["출처"] == "M01"
|
||||
assert first["값"]["가격"] and first["구분"]
|
||||
assert isinstance(first["값"]["가격"], int | float) and first["구분"] # 수(글이면 미리보기 0)
|
||||
dig = [r for r in _at(me, look.find, "굴착기") if r["출처"] == "M01"]
|
||||
assert dig and len({r["키"] for r in dig}) == len(dig) # 겹침 없음
|
||||
|
||||
@@ -98,3 +98,47 @@ def test_personal_only(world):
|
||||
look.get_items(layer, owner, user)
|
||||
assert e.value.status_code == code
|
||||
assert look.get_items("personal", None, user) == {"rows": []}
|
||||
|
||||
|
||||
def _stack_doc(key, no):
|
||||
"""줄 쌓기 기계 줄 하나(화면이 저장하는 꼴) — 기계='개인 …'."""
|
||||
var = {"기호": "P", "아래": "새", "위": "", "이름": NAME, "단위": "",
|
||||
"연결": {"갈래": "단가산출", "키": "GC000268", "입력": {"기계": f"'{no}'"}}} # fmt: skip
|
||||
line = {"이름": NAME, "단위": "hr", "비목": "묶음", "수량": "1", "단가": "P_새"}
|
||||
return {"꼴": "수식문서", "판": 1, "키": key, "이름": "sub1임시", "결과단위": "원",
|
||||
"변수": [var], "식": [], "금액": [line]} # fmt: skip
|
||||
|
||||
|
||||
def test_stack_line_copy(world):
|
||||
"""⑤ 줄 쌓기로 고른 내 기계 — 미리 셈 됨 · 저장 때 값 사본에 박힘 →
|
||||
고쳐도 금액 그대로 + 단가새값 → [단가 갱신] 바뀐 자원 1 → 지워도 마지막 값 + 지운키."""
|
||||
from M02_MasterTemplete import M02_Doc_Sk_Path as path
|
||||
from M02_MasterTemplete import M02_Labor_Ref as refs
|
||||
|
||||
me = world["personal"]
|
||||
made = _at(me, mym.create, {**_mine_row(), "값": {**_mine_row()["값"], "주연료": 2,
|
||||
"주연료종류": "경유", "조종원": 1, "조종원직종": "1048"}}) # fmt: skip
|
||||
key, no, was = made["줄"]["키"], made["줄"]["원문번호"], made["시간당"]["계"]
|
||||
sk = _at(
|
||||
me,
|
||||
lambda: refs.create("sangeun", {"이름": "sub1임시", "단위": "시간", "더한줄": []})["이름"],
|
||||
)
|
||||
doc = _stack_doc(sk, no)
|
||||
look_ = _at(me, path.preview, sk, {"문서": doc})
|
||||
assert look_["셈"]["계"] == was # 사본에 아직 없는 내 기계도 셈
|
||||
판 = _at(me, path.read, sk)["판"]
|
||||
_at(me, path.save, sk, {"문서": doc, "판": 판})
|
||||
copy = _at(me, lambda: store.read("sangeun", sk)["문서"]["수식"])
|
||||
assert key in [r["키"] for r in copy["단가"]] # 값 사본에 박힘
|
||||
_at(me, mym.update, key, {**made["줄"], "값": {**made["줄"]["값"], "가격": 3000}})
|
||||
now = _at(me, path.read, sk)
|
||||
assert now["셈"]["계"] == was and now["사본"]["단가새값"] is True
|
||||
job = _at(me, path.preview, sk, {"할일": "단가갱신"})
|
||||
assert [x["키"] for x in job["바뀐자원"]] == [key] and job["후"]["계"] > was
|
||||
_at(me, mym.delete, key)
|
||||
gone = _at(me, path.read, sk)
|
||||
assert gone["셈"]["계"] == was and gone["사본"]["지운키"] == [key]
|
||||
|
||||
|
||||
def _mine_row():
|
||||
return {"이름": NAME, "규격": "1㎾", "방식": "바로", "값": {"가격": 1000, "손료계수": 2000}}
|
||||
|
||||
Reference in New Issue
Block a user