fix: 리비전 업로드 시 구매확정 상태 상속 문제 해결
문제점: - 리비전 파일 업로드 시 모든 자재가 purchase_confirmed=false로 새로 저장됨 - 이전 리비전에서 구매확정한 자재가 다시 미구매 상태로 돌아가는 버그 해결방법: 1. perform_simple_revision_comparison 함수에서 구매확정 정보 반환 - purchase_confirmed, purchase_confirmed_at, purchase_confirmed_by - purchased_materials_map 딕셔너리로 반환 2. materials 테이블 insert 시 구매확정 상태 상속 - 자재 식별 키로 purchased_materials_map 확인 - 매칭되면 구매확정 상태와 메타데이터 상속 - 로그 출력: "🔥 구매확정 상태 상속: ..." 3. 디버깅 정보 개선 - 리비전 비교 결과에 excluded_purchased_count 추가 - 첫 번째 자재 저장 시 purchase_confirmed 상태 출력 동작 방식: 1. Rev.1에서 자재 A를 구매확정 → purchase_confirmed=true 2. Rev.2 업로드 시 자재 A가 포함되어 있으면 3. 리비전 비교에서 자재 A를 purchased_materials_map에 저장 4. 새 파일의 자재 A 저장 시 구매확정 상태 상속 5. Rev.2의 자재 A도 purchase_confirmed=true 유지 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -514,7 +514,8 @@ async def upload_file(
|
||||
# 🔄 리비전 비교 수행 (RULES.md 코딩 컨벤션 준수)
|
||||
revision_comparison = None
|
||||
materials_to_classify = materials_data
|
||||
|
||||
purchased_materials_map = {} # 구매확정된 자재 매핑 (키 -> 구매확정 정보)
|
||||
|
||||
if revision != "Rev.0": # 리비전 업로드인 경우만 비교
|
||||
print(f"🔍 [DEBUG] 리비전 비교 시작 - revision: {revision}, parent_file_id: {parent_file_id}")
|
||||
try:
|
||||
@@ -522,20 +523,24 @@ async def upload_file(
|
||||
print(f"🔍 [DEBUG] perform_simple_revision_comparison 호출 중...")
|
||||
revision_comparison = perform_simple_revision_comparison(db, job_no, parent_file_id, materials_data)
|
||||
print(f"🔍 [DEBUG] 리비전 비교 완료: {revision_comparison.keys() if revision_comparison else 'None'}")
|
||||
|
||||
|
||||
if revision_comparison.get("has_purchased_materials", False):
|
||||
print(f"📊 간단한 리비전 비교 결과:")
|
||||
print(f" - 구매확정된 자재: {revision_comparison.get('purchased_count', 0)}개")
|
||||
print(f" - 미구매 자재: {revision_comparison.get('unpurchased_count', 0)}개")
|
||||
print(f" - 신규 자재: {revision_comparison.get('new_count', 0)}개")
|
||||
print(f" - 변경된 자재: {revision_comparison.get('changed_count', 0)}개")
|
||||
|
||||
print(f" - 제외된 구매확정 자재: {revision_comparison.get('excluded_purchased_count', 0)}개")
|
||||
|
||||
# 신규 및 변경된 자재만 분류
|
||||
materials_to_classify = revision_comparison.get("materials_to_classify", [])
|
||||
print(f" - 분류 필요: {len(materials_to_classify)}개")
|
||||
|
||||
# 🔥 구매확정된 자재 매핑 정보 저장
|
||||
purchased_materials_map = revision_comparison.get("purchased_materials_map", {})
|
||||
print(f" - 구매확정 자재 매핑: {len(purchased_materials_map)}개")
|
||||
else:
|
||||
print("📝 이전 구매확정 자료 없음 - 전체 자재 분류")
|
||||
|
||||
|
||||
except Exception as e:
|
||||
print(f"⚠️ 리비전 비교 실패, 전체 자재 분류로 진행: {str(e)}")
|
||||
import traceback
|
||||
@@ -752,23 +757,42 @@ async def upload_file(
|
||||
if not full_material_grade and material_data.get("material_grade"):
|
||||
full_material_grade = material_data["material_grade"]
|
||||
|
||||
# 🔥 구매확정 상태 확인 (리비전인 경우)
|
||||
is_purchase_confirmed = False
|
||||
purchase_confirmed_at = None
|
||||
purchase_confirmed_by = None
|
||||
|
||||
if parent_file_id and purchased_materials_map:
|
||||
# 자재 식별 키 생성 (리비전 비교와 동일한 방식)
|
||||
material_key = f"{description.strip().upper()}|{size_spec or ''}"
|
||||
|
||||
if material_key in purchased_materials_map:
|
||||
# 이전 리비전에서 구매확정된 자재
|
||||
purchased_info = purchased_materials_map[material_key]
|
||||
is_purchase_confirmed = True
|
||||
purchase_confirmed_at = purchased_info.get("purchase_confirmed_at")
|
||||
purchase_confirmed_by = purchased_info.get("purchase_confirmed_by")
|
||||
print(f"🔥 구매확정 상태 상속: {description[:50]}...")
|
||||
|
||||
# 기본 자재 정보 저장
|
||||
material_insert_query = text("""
|
||||
INSERT INTO materials (
|
||||
file_id, original_description, quantity, unit, size_spec,
|
||||
main_nom, red_nom, material_grade, full_material_grade, line_number, row_number,
|
||||
classified_category, classification_confidence, is_verified,
|
||||
drawing_name, line_no, created_at
|
||||
file_id, original_description, quantity, unit, size_spec,
|
||||
main_nom, red_nom, material_grade, full_material_grade, line_number, row_number,
|
||||
classified_category, classification_confidence, is_verified,
|
||||
drawing_name, line_no, created_at,
|
||||
purchase_confirmed, purchase_confirmed_at, purchase_confirmed_by
|
||||
)
|
||||
VALUES (
|
||||
:file_id, :original_description, :quantity, :unit, :size_spec,
|
||||
:main_nom, :red_nom, :material_grade, :full_material_grade, :line_number, :row_number,
|
||||
:classified_category, :classification_confidence, :is_verified,
|
||||
:drawing_name, :line_no, :created_at
|
||||
:drawing_name, :line_no, :created_at,
|
||||
:purchase_confirmed, :purchase_confirmed_at, :purchase_confirmed_by
|
||||
)
|
||||
RETURNING id
|
||||
""")
|
||||
|
||||
|
||||
# 첫 번째 자재에 대해서만 디버그 출력
|
||||
if materials_inserted == 0:
|
||||
print(f"첫 번째 자재 저장:")
|
||||
@@ -777,7 +801,8 @@ async def upload_file(
|
||||
print(f" category: {classification_result.get('category', 'UNCLASSIFIED')}")
|
||||
print(f" drawing_name: {material_data.get('dwg_name')}")
|
||||
print(f" line_no: {material_data.get('line_num')}")
|
||||
|
||||
print(f" purchase_confirmed: {is_purchase_confirmed}")
|
||||
|
||||
material_result = db.execute(material_insert_query, {
|
||||
"file_id": file_id,
|
||||
"original_description": material_data["original_description"],
|
||||
@@ -795,7 +820,10 @@ async def upload_file(
|
||||
"is_verified": False,
|
||||
"drawing_name": material_data.get("dwg_name"),
|
||||
"line_no": material_data.get("line_num"),
|
||||
"created_at": datetime.now()
|
||||
"created_at": datetime.now(),
|
||||
"purchase_confirmed": is_purchase_confirmed,
|
||||
"purchase_confirmed_at": purchase_confirmed_at,
|
||||
"purchase_confirmed_by": purchase_confirmed_by
|
||||
})
|
||||
|
||||
material_id = material_result.fetchone()[0]
|
||||
@@ -4066,12 +4094,12 @@ def perform_simple_revision_comparison(db: Session, job_no: str, parent_file_id:
|
||||
}
|
||||
"""
|
||||
try:
|
||||
# 1. 이전 파일의 모든 자재 조회
|
||||
# 1. 이전 파일의 모든 자재 조회 (구매확정 정보 포함)
|
||||
previous_materials_query = text("""
|
||||
SELECT original_description, classified_category, size_spec, material_grade,
|
||||
main_nom, red_nom, drawing_name, line_no,
|
||||
COALESCE(total_quantity, quantity, 0) as quantity, unit,
|
||||
purchase_confirmed
|
||||
purchase_confirmed, purchase_confirmed_at, purchase_confirmed_by
|
||||
FROM materials
|
||||
WHERE file_id = :parent_file_id
|
||||
ORDER BY id
|
||||
@@ -4111,7 +4139,9 @@ def perform_simple_revision_comparison(db: Session, job_no: str, parent_file_id:
|
||||
"line_no": material.line_no,
|
||||
"quantity": float(material.quantity or 0),
|
||||
"unit": material.unit,
|
||||
"purchase_confirmed": material.purchase_confirmed
|
||||
"purchase_confirmed": material.purchase_confirmed,
|
||||
"purchase_confirmed_at": material.purchase_confirmed_at,
|
||||
"purchase_confirmed_by": material.purchase_confirmed_by
|
||||
}
|
||||
|
||||
if key in previous_dict:
|
||||
@@ -4216,6 +4246,7 @@ def perform_simple_revision_comparison(db: Session, job_no: str, parent_file_id:
|
||||
"excluded_purchased_count": excluded_purchased_count,
|
||||
"materials_to_classify": materials_to_classify, # 신규 자재만
|
||||
"removed_materials": removed_materials, # 삭제된 자재
|
||||
"purchased_materials_map": purchased_dict, # 🔥 구매확정된 자재 매핑 정보
|
||||
"total_previous": len(previous_dict),
|
||||
"total_new": len(new_dict)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user