- to-base 몸 환산? · 환산 없이 단위 성격 다름 = 후 None · 필요 ["환산"](막지 않음 · 화면 붉은 칸) - 화면 bind = 블록 풀이 그 기초 후보 바인딩(엑셀 값 · 기본) + 블록 검산 입력 필요 · 줄 검산(빈 입력값)은 옵션을 못 읽었음 - 가져온 식 SK = M01 짝 없음 — 시트 M01바뀜 · 짝잃음 안 띄움(저장 M01판이 바탕 줄과 달라 늘 떴음) - 시험 test_793_3b 8 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
191 lines
7.0 KiB
Python
191 lines
7.0 KiB
Python
"""M02 단가산출(SK) 셈 길(PLAN 715-1b) — `POST /api/m02/layers/{층}/sangeun/calc` ·
|
|
[단가산출로 저장](715-3) `POST /api/m02/layers/{층}/sangeun/from-line`(층 쓰기 권한) ·
|
|
식 칸 검사(792-1) `POST /api/m02/layers/{층}/sangeun/formula-check`(셈 없음 · 층 읽기 권한) ·
|
|
가져온 식(793-2 · `M02_Sangeun_Imported`) `…/sangeun/imported`(만들기 · 층 쓰기) · `/price` ·
|
|
`/link` · `/to-base`(화면 캐시 문서 고침 · 저장 없음 · 층 읽기) ·
|
|
불러오기 단산 블록 → 가져온 식(793-3b · `M02_Sangeun_FromHopyo`) `…/sangeun/from-hopyo`
|
|
(만들 층 쓰기).
|
|
|
|
저장 안 함 · 로그인 사용자 · 층 읽기 권한(`Router_Items._root`) · 화면은 최신 응답만.
|
|
몸 = `문서`(저장 전 화면 문서) 또는 `키`(그 층 저장본) + `입력값`(열린입력 · 시험 값) ·
|
|
`보기` false = 보기 덧칸(`글` · `중간` · 750-1) 안 지음(바탕 원값 셈처럼 금액만 쓸 때).
|
|
문서 읽기 · 쓰기 · 새로 · 복사 · 지우기는 양식 길 · 서고 길 그대로(종류 `sangeun`).
|
|
⚠ 등록은 `main.py`(로그인만).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
from pydantic import BaseModel
|
|
|
|
from common_util.common_util_auth import verify_session
|
|
from M02_MasterTemplete import M02_MasterTemplete_Store as store
|
|
from M02_MasterTemplete import M02_Sangeun_Calc as calc
|
|
from M02_MasterTemplete import M02_Sangeun_Doc as sd
|
|
from M02_MasterTemplete import M02_Sangeun_Formula as fx
|
|
from M02_MasterTemplete import M02_Sangeun_FromHopyo as from_hopyo
|
|
from M02_MasterTemplete import M02_Sangeun_Imported as imp
|
|
from M02_MasterTemplete.M02_MasterTemplete_Router_Items import Layer, Session, _call, _root
|
|
|
|
router = APIRouter(prefix="/api/m02", tags=["M02 MasterTemplete Sangeun"])
|
|
|
|
|
|
class SangeunCalcBody(BaseModel):
|
|
문서: dict[str, Any] | None = None
|
|
키: str | None = None
|
|
입력값: dict[str, Any] | None = None
|
|
보기: bool = True
|
|
|
|
|
|
def _calc(body: SangeunCalcBody) -> dict[str, Any]:
|
|
doc = body.문서
|
|
if doc is None:
|
|
if not sd.KEY.match(str(body.키 or "")):
|
|
raise store.StoreError(400, "문서 또는 키(SK-######)")
|
|
doc = store.read(sd.KIND, str(body.키))["문서"]
|
|
return calc.calc_doc(doc, body.입력값, body.보기)
|
|
|
|
|
|
class FromLineBody(BaseModel):
|
|
줄: dict[str, Any]
|
|
이름: str
|
|
단위: str
|
|
새로: bool = False # 같은 내용 409 뒤 — 그래도 새로(733-2)
|
|
씀: str | None = None # 같은 내용 409 뒤 — 그 SK 씀
|
|
|
|
|
|
@router.post("/layers/{layer}/sangeun/from-line")
|
|
def sangeun_from_line(
|
|
layer: Layer,
|
|
body: FromLineBody,
|
|
owner: str | None = None,
|
|
session: Session = Depends(verify_session),
|
|
) -> dict:
|
|
"""[단가산출로 저장](715-3) — 일위대가 줄 → 그 층 새 단가산출 · 답 = 새 키 + 바꿀 참조 줄."""
|
|
folder = _root(session, layer, owner, write=True)
|
|
return _call(folder, calc.from_line, body.줄, body.이름, body.단위, body.새로, body.씀)
|
|
|
|
|
|
@router.post("/layers/{layer}/sangeun/calc")
|
|
def calc_sangeun(
|
|
layer: Layer,
|
|
body: SangeunCalcBody,
|
|
owner: str | None = None,
|
|
session: Session = Depends(verify_session),
|
|
) -> dict:
|
|
"""단가산출 셈 — 줄(cid · 덮개 · 원값) · 기준 · 1단위 · 짝잃음(저장 안 함)."""
|
|
if body.문서 is None and body.키 is None:
|
|
raise HTTPException(status_code=400, detail="문서 또는 키")
|
|
return _call(_root(session, layer, owner), _calc, body)
|
|
|
|
|
|
class FormulaCheckBody(BaseModel):
|
|
문서: dict[str, Any]
|
|
자리: str
|
|
식: str
|
|
|
|
|
|
@router.post("/layers/{layer}/sangeun/formula-check")
|
|
def check_formula(
|
|
layer: Layer,
|
|
body: FormulaCheckBody,
|
|
owner: str | None = None,
|
|
session: Session = Depends(verify_session),
|
|
) -> dict:
|
|
"""식 칸 검사(792-1) — {되나, 까닭, 알림, 식(엔진), 글(이름 꼴)} · 셈 · 저장 없음."""
|
|
return _call(_root(session, layer, owner), fx.check_doc, body.문서, body.자리, body.식)
|
|
|
|
|
|
class ImportedBody(BaseModel):
|
|
로직: dict[str, Any]
|
|
원본: dict[str, Any] | None = None
|
|
이름: str = ""
|
|
단위: str = ""
|
|
구분: str = ""
|
|
상세구분: str = ""
|
|
새로: bool = False
|
|
씀: str | None = None
|
|
|
|
|
|
@router.post("/layers/{layer}/sangeun/imported")
|
|
def sangeun_imported(
|
|
layer: Layer,
|
|
body: ImportedBody,
|
|
owner: str | None = None,
|
|
session: Session = Depends(verify_session),
|
|
) -> dict:
|
|
"""가져온 식 단가산출 만들기(793-2) — 답 = {이름, 검산, 단가기준} · 같은 내용 409."""
|
|
folder = _root(session, layer, owner, write=True)
|
|
head = {"구분": body.구분, "상세구분": body.상세구분}
|
|
args = (body.로직, body.원본, body.이름, body.단위, head, body.새로, body.씀)
|
|
return _call(folder, _sd(imp.create), *args)
|
|
|
|
|
|
class FromHopyoBody(BaseModel):
|
|
층: Layer
|
|
주인: str | None = None
|
|
키: str
|
|
번: int
|
|
이름: str = ""
|
|
|
|
|
|
@router.post("/layers/{layer}/sangeun/from-hopyo")
|
|
def sangeun_from_hopyo(
|
|
layer: Layer,
|
|
body: FromHopyoBody,
|
|
owner: str | None = None,
|
|
session: Session = Depends(verify_session),
|
|
) -> dict:
|
|
"""불러오기 단산 블록 → 가져온 식 SK(793-3b) — 경로 층 = 만들 층 · 몸 층 = 파일 층 ·
|
|
답 = {이름, 검산, 단가기준, 다시씀}(같은 내용 = 그 SK)."""
|
|
folder = _root(session, layer, owner, write=True)
|
|
source = _root(session, body.층, body.주인)
|
|
return _call(folder, _sd(from_hopyo.make), source, body.키, body.번, body.이름)
|
|
|
|
|
|
class ImportedEditBody(BaseModel):
|
|
문서: dict[str, Any]
|
|
기준: str | None = None # price
|
|
자리: str | None = None # link
|
|
이음: str | None = None # link
|
|
로직: str | None = None # to-base
|
|
입력값: dict[str, Any] | None = None # to-base
|
|
환산: dict[str, Any] | None = None # to-base(793-3b · SK 단위 환산 계수)
|
|
|
|
|
|
def _sd(fn: Any) -> Any:
|
|
"""`sd.DocError` → 400 · 422(`store.StoreError`)."""
|
|
|
|
def run(*args: Any) -> Any:
|
|
try:
|
|
return calc.labor._json(fn(*args))
|
|
except sd.DocError as e:
|
|
raise calc._fail(e) from e
|
|
|
|
return run
|
|
|
|
|
|
_EDIT = {
|
|
"price": lambda b: (imp.to_price, b.문서, b.기준),
|
|
"link": lambda b: (imp.link, b.문서, b.자리, b.이음),
|
|
"to-base": lambda b: (imp.to_base, b.문서, b.로직, b.입력값, b.환산),
|
|
}
|
|
|
|
|
|
@router.post("/layers/{layer}/sangeun/imported/{how}")
|
|
def sangeun_imported_edit(
|
|
layer: Layer,
|
|
how: str,
|
|
body: ImportedEditBody,
|
|
owner: str | None = None,
|
|
session: Session = Depends(verify_session),
|
|
) -> dict:
|
|
"""가져온 식 고치기(793-2) — price [우리 · 엑셀 단가로] · link 이음 고름 · to-base [우리 기초로
|
|
바꾸기] · 답 = 고친 문서(화면 캐시 · 저장 없음) + 전 · 후 금액."""
|
|
if how not in _EDIT:
|
|
raise HTTPException(status_code=404, detail="price · link · to-base")
|
|
fn, *args = _EDIT[how](body)
|
|
return _call(_root(session, layer, owner), _sd(fn), *args)
|