auto: 2026-09-20 02:30 (ESD_LAPTOP)
This commit is contained in:
@@ -92,9 +92,11 @@ def files_of(group: str) -> list[dict]:
|
||||
return out
|
||||
|
||||
|
||||
def rows(file: str, page: int, size: int, q: str) -> dict:
|
||||
def rows(file: str, page: int, size: int, q: str, unlinked: bool = False) -> dict:
|
||||
data, version = read(file)
|
||||
hits = [r for r in data.get(items_key(data)) or [] if _hit(r, q)]
|
||||
if unlinked: # 품셈재료 — 아직 못 이은 줄
|
||||
hits = [r for r in hits if not r.get("연결")]
|
||||
page, size = max(page, 1), min(max(size, 1), 500)
|
||||
return {
|
||||
"file": file,
|
||||
@@ -192,7 +194,8 @@ def _brief(ref: str, row: dict) -> dict:
|
||||
|
||||
|
||||
def _prices(whole, row: dict) -> dict:
|
||||
"""호표 요소 → 요소 줄 요약(단가 자동 칸) · `{이름}` 낀 열쇠·하위 로직은 계산 때 정해짐."""
|
||||
"""호표 요소 → 요소 줄 요약(단가 자동 칸) · `{이름}` 낀 열쇠·하위 로직은 계산 때 정해짐.
|
||||
품셈재료는 연결을 따라간 낮은 값과 출처 · 자재지역 후보는 계산 때 정해짐(값 None)."""
|
||||
out = {}
|
||||
for item in row.get("호표") or []:
|
||||
ref = str(item.get("요소", ""))
|
||||
@@ -201,6 +204,13 @@ def _prices(whole, row: dict) -> dict:
|
||||
out[ref] = _brief(ref, whole.get(ref))
|
||||
except cm.mf.FormulaError:
|
||||
out[ref] = None
|
||||
continue
|
||||
if ref.startswith(cm.mf.LINKED):
|
||||
try:
|
||||
value, source = cm.mf.element(whole, ref, {})
|
||||
except (cm.mf.FormulaError, KeyError, TypeError):
|
||||
value, source = None, None
|
||||
out[ref].update({"값": value, "출처": source})
|
||||
return out
|
||||
|
||||
|
||||
@@ -219,6 +229,50 @@ def elements(group: str, q: str, limit: int) -> dict:
|
||||
return {"total": len(hits), "items": hits[: min(max(limit, 1), 200)]}
|
||||
|
||||
|
||||
_PICK = {
|
||||
"procure": "재료_나라장터자재.json",
|
||||
"price": "재료_시중물가.json",
|
||||
"job": "인력_건설노임.json",
|
||||
}
|
||||
|
||||
|
||||
def _squash(text) -> str:
|
||||
return "".join(str(text or "").lower().split())
|
||||
|
||||
|
||||
def _lowest(value) -> object:
|
||||
"""시중물가 줄 — 시중 다섯 칸 · 조달 값 가운데 낮은 값 · 그 밖은 `값` 그대로."""
|
||||
if not isinstance(value, dict):
|
||||
return value
|
||||
nums = [v for v in value["시중"].values() if isinstance(v, (int, float))]
|
||||
supply = value["조달"].get("값")
|
||||
return min(nums + ([supply] if supply is not None else []), default=None)
|
||||
|
||||
|
||||
def pick(kind: str, q: str, limit: int) -> dict:
|
||||
"""고르기 창 — `procure` 나라장터자재(ref = 나라장터:<열쇠>) · `price` 시중물가(관급 조달 줄 포함 · ref = 열쇠)
|
||||
· `job` 값 있는 건설노임 직종(ref = 열쇠) · 이름·규격 낱말이 모두 들어간 줄."""
|
||||
if kind not in _PICK:
|
||||
raise StoreError(404, f"없는 고르기 「{kind}」")
|
||||
words = [_squash(w) for w in q.split()]
|
||||
hits = []
|
||||
for row in read(_PICK[kind])[0].get("줄") or []:
|
||||
if kind == "job" and row.get("값") is None:
|
||||
continue
|
||||
text = _squash(f"{row.get('이름')} {row.get('규격')}")
|
||||
if all(w in text for w in words):
|
||||
key = str(row.get("열쇠"))
|
||||
hits.append(
|
||||
{
|
||||
"ref": f"나라장터:{key}" if kind == "procure" else key,
|
||||
**{k: row.get(k) for k in ("이름", "규격", "단위")},
|
||||
"값": _lowest(row.get("값")),
|
||||
"관급": kind == "price" and row["값"]["조달"].get("값") is not None,
|
||||
}
|
||||
)
|
||||
return {"total": len(hits), "items": hits[: min(max(limit, 1), 200)]}
|
||||
|
||||
|
||||
# ── 시험 계산 ──────────────────────────────────────────────────────────
|
||||
def _swap(files: dict, book: str, key: str, row: dict, file: str | None) -> None:
|
||||
"""저장 전 시험 — 메모리 사본에서 그 로직을 고친 줄로 바꿈(없으면 `file` 에 더함)."""
|
||||
|
||||
Reference in New Issue
Block a user