Merge remote-tracking branch 'origin/sub_laptop_6' into sub_laptop_8
This commit is contained in:
@@ -11,8 +11,13 @@
|
||||
원가 · 공기) · 단가 책 · `estimation` 설정 구획 지움 · 서고 사본 정리 · 견적서 파일 남김 →
|
||||
답 = GET 꼴(기준 = 지금 B08 저장본 + 지금 M01 단가) · 단계 = [저장]과 같음
|
||||
POST /api/projects/{id}/estimation/prices {user?}
|
||||
[단가 갱신] — 수요 단가 전부를 지금 M01 값으로 새로 굳힘 · user = 화면 캐시(296 ·
|
||||
지운 줄 · 그 사본은 수요에서 뺌 · 저장은 안 함) · M01 원본이 지워진 줄 = 굳힌 값 그대로
|
||||
[업데이트] — 원본이 바뀐 구조물 사본 재적용(703-3 · `B09_Estimation_Refresh`) →
|
||||
수요 단가 전부를 지금 M01 값으로 새로 굳힘 · user = 화면 캐시(296 · 지운 줄 · 그 사본은
|
||||
수요에서 뺌 · 저장은 안 함) · M01 원본이 지워진 줄 = 굳힌 값 그대로 · 덮개 그대로 ·
|
||||
답 notes 첫 줄 = 바뀐 수
|
||||
POST /api/projects/{id}/estimation/prices/preview {user?}
|
||||
[업데이트] 미리 보기(703-3) — 바뀌는 단가 줄 · 다시 가져올 사본 · 지킬 고친 칸 ·
|
||||
노임 판(쓰지 않음)
|
||||
POST /api/projects/{id}/estimation/logic-preview {code, given, rate, picks}
|
||||
「운반 단가」 모달 계산 절차(253-3) — 그 로직 한 산근을 프로젝트 단가로 풀어 글 줄 · 단가 ·
|
||||
저장 안 함(`render_sangeun_text` 를 `Sangeun.Solver` 로) · `blocks` = 칸 나눔(277-2)
|
||||
@@ -24,6 +29,10 @@
|
||||
운반공 줄 = {given, own, dist} 같이 → 거리 값 사본(263-2 · 폴더 `~값 해시`)
|
||||
POST /api/projects/{id}/estimation/library-inputs {kind, layer, owner, key, lib?}
|
||||
「운반 단가」 모달(263-2) — 담은 로직 줄 입력 · 값(읽기만 · 권한 = library 길과 같음)
|
||||
POST /api/projects/{id}/estimation/daega/personal {cover, name?, overwrite?, user?}
|
||||
「내 자료집에 저장」(703-2) — 펼친 일위대가 → 개인 층 사전조합
|
||||
(`B09_Estimation_Daega_Personal`) · user = 화면 캐시 덮개 ·
|
||||
같은 이름 = 409 {같은이름} → 덮어쓰기(overwrite = 키) · 새 이름
|
||||
운반 사본 연결 = 셈 때마다 거리로 사본 다시 고름(`Bill_Library.resolve_hauls` · `fix_keys`).
|
||||
|
||||
저장 자리 = 프로젝트 안 `B09_Estimation/v1/`(`B09_Estimation_Store`) ·
|
||||
@@ -53,7 +62,9 @@ from B08_Quantity.B08_Quantity_Router_Material import material_sheets
|
||||
from B08_Quantity.B08_Quantity_Router_Milestone import read_data as read_milestone
|
||||
from B08_Quantity.B08_Quantity_Router_Milestone import site_info
|
||||
from B09_Estimation import B09_Estimation_Bill_Library as library
|
||||
from B09_Estimation import B09_Estimation_Daega_Personal as personal
|
||||
from B09_Estimation import B09_Estimation_Prices as prices
|
||||
from B09_Estimation import B09_Estimation_Refresh as refresh
|
||||
from B09_Estimation import B09_Estimation_Sangeun as sangeun
|
||||
from B09_Estimation import B09_Estimation_Store as store
|
||||
from B09_Estimation.B09_Estimation_Bill_Items import bill_items, hopyo_prices
|
||||
@@ -71,6 +82,7 @@ from common_util.common_util_project_settings import reset_section
|
||||
from common_util.common_util_workflow_state import mark_stage
|
||||
from M02_MasterTemplete import M02_Layer_Access as access
|
||||
from M02_MasterTemplete.M02_Item_Snapshot import importer
|
||||
from M02_MasterTemplete.M02_MasterTemplete_Router_Items import _call, _root
|
||||
|
||||
try: # 252 공기 초안(draft 폴더 · 지우면 공기 탭 원천 없이)
|
||||
from B09_Estimation.draft import B09_Draft_Schedule_Source as schedule_draft
|
||||
@@ -264,16 +276,44 @@ async def estimation_reset(project_id: UUID) -> dict[str, Any]:
|
||||
|
||||
@router.post("/{project_id}/estimation/prices")
|
||||
async def refresh_prices(
|
||||
project_id: UUID, body: dict[str, Any] | None = Body(None)
|
||||
project_id: UUID,
|
||||
body: dict[str, Any] | None = Body(None),
|
||||
session: dict[str, Any] = Depends(verify_session),
|
||||
) -> dict[str, Any]:
|
||||
"""[업데이트] 한 곳(703-3) — 원본이 바뀐 구조물 사본 재적용 → 단가 책 다시 굳힘 ·
|
||||
덮개 그대로."""
|
||||
root = await _project_root(project_id)
|
||||
raw = (body or {}).get("user")
|
||||
draft = store.clean_user(raw) if isinstance(raw, dict) else None # 296 화면 캐시(저장 안 함)
|
||||
again = await asyncio.to_thread(refresh.reapply_changed, root, importer(session))
|
||||
keys = await _demand(root, draft)
|
||||
old = await asyncio.to_thread(store.read_book, root)
|
||||
book = await asyncio.to_thread(prices.refresh_book, keys, old)
|
||||
await asyncio.to_thread(store.write_book, root, book)
|
||||
return await payload(project_id, root, draft)
|
||||
out = await payload(project_id, root, draft)
|
||||
diff = prices.book_diff(old, book)
|
||||
cells = refresh.cover_cells((draft or out.get("user") or {}).get("daega_cover"))
|
||||
out["notes"] = [
|
||||
f"업데이트 — 단가 줄 {diff['new'] + diff['changed']} 바뀜 · 구조물 사본 "
|
||||
f"{len(again['다시'])} 다시 가져옴 · 고친 칸 {cells} 그대로",
|
||||
*(f"재적용 못 함 {why}" for why in again["막힘"]),
|
||||
*(out.get("notes") or []),
|
||||
]
|
||||
return out
|
||||
|
||||
|
||||
@router.post("/{project_id}/estimation/prices/preview")
|
||||
async def refresh_preview(
|
||||
project_id: UUID, body: dict[str, Any] | None = Body(None)
|
||||
) -> dict[str, Any]:
|
||||
"""[업데이트] 미리 보기(703-3) — 바뀌는 단가 줄 · 다시 가져올 사본 · 지킬 고친 칸 · 노임 판."""
|
||||
root = await _project_root(project_id)
|
||||
raw = (body or {}).get("user")
|
||||
draft = store.clean_user(raw) if isinstance(raw, dict) else None
|
||||
keys = await _demand(root, draft)
|
||||
book = await asyncio.to_thread(store.read_book, root)
|
||||
user = draft if draft is not None else await asyncio.to_thread(store.read_user, root)
|
||||
return await asyncio.to_thread(refresh.preview, root, book, keys, user.get("daega_cover"))
|
||||
|
||||
|
||||
class PreviewBody(BaseModel):
|
||||
@@ -385,6 +425,38 @@ async def library_inputs(
|
||||
return {"lines": lines}
|
||||
|
||||
|
||||
class PersonalBody(BaseModel):
|
||||
cover: str = Field(min_length=1, max_length=200)
|
||||
name: str | None = Field(None, max_length=200)
|
||||
overwrite: str | None = Field(None, max_length=20)
|
||||
user: dict[str, Any] | None = None
|
||||
|
||||
|
||||
@router.post("/{project_id}/estimation/daega/personal")
|
||||
async def save_personal(
|
||||
project_id: UUID, body: PersonalBody, session: dict[str, Any] = Depends(verify_session)
|
||||
) -> dict[str, Any]:
|
||||
root = await _project_root(project_id)
|
||||
raw = (
|
||||
body.user if isinstance(body.user, dict) else await asyncio.to_thread(store.read_user, root)
|
||||
)
|
||||
cover = store.clean_user(raw).get("daega_cover") or {}
|
||||
try:
|
||||
made = await asyncio.to_thread(personal.build, root, body.cover, cover, body.name)
|
||||
except LookupError as error:
|
||||
raise HTTPException(status_code=404, detail=str(error)) from error
|
||||
if not made["문서"]["이름"]:
|
||||
raise HTTPException(status_code=400, detail="이름이 빔")
|
||||
folder = await asyncio.to_thread(_root, session, "personal", None, True)
|
||||
got = await asyncio.to_thread(_call, folder, personal.write, made["문서"], body.overwrite)
|
||||
return {
|
||||
"키": got["이름"],
|
||||
"이름": made["문서"]["이름"],
|
||||
"담음": made["담음"],
|
||||
"안담음": made["안담음"],
|
||||
}
|
||||
|
||||
|
||||
# 166-4 견적서 파일 길 — 같은 머리 · 같은 권한
|
||||
router.include_router(quotes_router)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user