파이프 길이 계산 및 엑셀 내보내기 버그 수정
- 자재 비교에서 파이프 길이 합산 로직 수정 - 프론트엔드에서 혼란스러운 '평균단위' 표시 제거 - 파이프 변경사항에 실제 이전/현재 총길이 표시 - 엑셀 내보내기에서 '초기화되지 않은 변수' 오류 수정 - 리비전 비교에서 파이프 길이 변화 계산 개선
This commit is contained in:
@@ -386,7 +386,7 @@ async def perform_material_comparison(
|
||||
|
||||
if material_hash not in previous_materials:
|
||||
# 완전히 새로운 항목
|
||||
new_items.append({
|
||||
new_item = {
|
||||
"material_hash": material_hash,
|
||||
"description": current_item["description"],
|
||||
"size_spec": current_item["size_spec"],
|
||||
@@ -394,7 +394,11 @@ async def perform_material_comparison(
|
||||
"quantity": current_qty,
|
||||
"category": current_item["category"],
|
||||
"unit": current_item["unit"]
|
||||
})
|
||||
}
|
||||
# 파이프인 경우 pipe_details 정보 포함
|
||||
if current_item.get("pipe_details"):
|
||||
new_item["pipe_details"] = current_item["pipe_details"]
|
||||
new_items.append(new_item)
|
||||
|
||||
else:
|
||||
# 기존 항목 - 수량 변경 체크
|
||||
@@ -402,7 +406,7 @@ async def perform_material_comparison(
|
||||
qty_change = current_qty - previous_qty
|
||||
|
||||
if qty_change != 0:
|
||||
modified_items.append({
|
||||
modified_item = {
|
||||
"material_hash": material_hash,
|
||||
"description": current_item["description"],
|
||||
"size_spec": current_item["size_spec"],
|
||||
@@ -412,12 +416,30 @@ async def perform_material_comparison(
|
||||
"quantity_change": qty_change,
|
||||
"category": current_item["category"],
|
||||
"unit": current_item["unit"]
|
||||
})
|
||||
}
|
||||
# 파이프인 경우 이전/현재 pipe_details 모두 포함
|
||||
if current_item.get("pipe_details"):
|
||||
modified_item["pipe_details"] = current_item["pipe_details"]
|
||||
|
||||
# 이전 리비전 pipe_details도 포함
|
||||
previous_item = previous_materials[material_hash]
|
||||
if previous_item.get("pipe_details"):
|
||||
modified_item["previous_pipe_details"] = previous_item["pipe_details"]
|
||||
|
||||
# 실제 길이 변화 계산 (현재 총길이 - 이전 총길이)
|
||||
if current_item.get("pipe_details"):
|
||||
current_total = current_item["pipe_details"]["total_length_mm"]
|
||||
previous_total = previous_item["pipe_details"]["total_length_mm"]
|
||||
length_change = current_total - previous_total
|
||||
modified_item["length_change"] = length_change
|
||||
print(f"🔢 실제 길이 변화: {current_item['description'][:50]} - 이전:{previous_total:.0f}mm → 현재:{current_total:.0f}mm (변화:{length_change:+.0f}mm)")
|
||||
|
||||
modified_items.append(modified_item)
|
||||
|
||||
# 삭제된 항목 찾기
|
||||
for material_hash, previous_item in previous_materials.items():
|
||||
if material_hash not in current_materials:
|
||||
removed_items.append({
|
||||
removed_item = {
|
||||
"material_hash": material_hash,
|
||||
"description": previous_item["description"],
|
||||
"size_spec": previous_item["size_spec"],
|
||||
@@ -425,7 +447,11 @@ async def perform_material_comparison(
|
||||
"quantity": previous_item["quantity"],
|
||||
"category": previous_item["category"],
|
||||
"unit": previous_item["unit"]
|
||||
})
|
||||
}
|
||||
# 파이프인 경우 pipe_details 정보 포함
|
||||
if previous_item.get("pipe_details"):
|
||||
removed_item["pipe_details"] = previous_item["pipe_details"]
|
||||
removed_items.append(removed_item)
|
||||
|
||||
return {
|
||||
"summary": {
|
||||
@@ -444,37 +470,110 @@ async def get_materials_by_hash(db: Session, file_id: int) -> Dict[str, Dict]:
|
||||
"""파일의 자재를 해시별로 그룹화하여 조회"""
|
||||
import hashlib
|
||||
|
||||
print(f"🚨🚨🚨 get_materials_by_hash 호출됨! file_id={file_id} 🚨🚨🚨")
|
||||
|
||||
query = text("""
|
||||
SELECT
|
||||
original_description,
|
||||
size_spec,
|
||||
material_grade,
|
||||
SUM(quantity) as quantity,
|
||||
classified_category,
|
||||
unit
|
||||
FROM materials
|
||||
WHERE file_id = :file_id
|
||||
GROUP BY original_description, size_spec, material_grade, classified_category, unit
|
||||
m.id,
|
||||
m.original_description,
|
||||
m.size_spec,
|
||||
m.material_grade,
|
||||
m.quantity,
|
||||
m.classified_category,
|
||||
m.unit,
|
||||
pd.length_mm,
|
||||
m.line_number
|
||||
FROM materials m
|
||||
LEFT JOIN pipe_details pd ON m.id = pd.material_id
|
||||
WHERE m.file_id = :file_id
|
||||
ORDER BY m.line_number
|
||||
""")
|
||||
|
||||
result = db.execute(query, {"file_id": file_id})
|
||||
materials = result.fetchall()
|
||||
|
||||
print(f"🔍 쿼리 결과 개수: {len(materials)}")
|
||||
if len(materials) > 0:
|
||||
print(f"🔍 첫 번째 자료 샘플: {materials[0]}")
|
||||
else:
|
||||
print(f"❌ 자료가 없음! file_id={file_id}")
|
||||
|
||||
# 🔄 같은 파이프들을 Python에서 올바르게 그룹핑
|
||||
materials_dict = {}
|
||||
for mat in materials:
|
||||
# 자재 해시 생성 (description + size_spec + material_grade)
|
||||
hash_source = f"{mat[0] or ''}|{mat[1] or ''}|{mat[2] or ''}"
|
||||
hash_source = f"{mat[1] or ''}|{mat[2] or ''}|{mat[3] or ''}"
|
||||
material_hash = hashlib.md5(hash_source.encode()).hexdigest()
|
||||
|
||||
materials_dict[material_hash] = {
|
||||
"material_hash": material_hash,
|
||||
"description": mat[0], # original_description -> description
|
||||
"size_spec": mat[1],
|
||||
"material_grade": mat[2],
|
||||
"quantity": float(mat[3]) if mat[3] else 0.0,
|
||||
"category": mat[4], # classified_category -> category
|
||||
"unit": mat[5] or 'EA'
|
||||
}
|
||||
print(f"📝 개별 자재: {mat[1][:50]}... ({mat[2]}) - 수량: {mat[4]}, 길이: {mat[7]}mm")
|
||||
|
||||
if material_hash in materials_dict:
|
||||
# 🔄 기존 항목에 수량 합계
|
||||
existing = materials_dict[material_hash]
|
||||
existing["quantity"] += float(mat[4]) if mat[4] else 0.0
|
||||
existing["line_number"] += f", {mat[8]}" if mat[8] else ""
|
||||
|
||||
# 파이프인 경우 길이 정보 합산
|
||||
if mat[5] == 'PIPE' and mat[7] is not None:
|
||||
if "pipe_details" in existing:
|
||||
# 총길이 합산: 기존 총길이 + (현재 수량 × 현재 길이)
|
||||
current_total = existing["pipe_details"]["total_length_mm"]
|
||||
current_count = existing["pipe_details"]["pipe_count"]
|
||||
|
||||
new_length = float(mat[4]) * float(mat[7]) # 수량 × 단위길이
|
||||
existing["pipe_details"]["total_length_mm"] = current_total + new_length
|
||||
existing["pipe_details"]["pipe_count"] = current_count + float(mat[4])
|
||||
|
||||
# 평균 단위 길이 재계산
|
||||
total_length = existing["pipe_details"]["total_length_mm"]
|
||||
total_count = existing["pipe_details"]["pipe_count"]
|
||||
existing["pipe_details"]["length_mm"] = total_length / total_count
|
||||
|
||||
print(f"🔄 파이프 합산: {mat[1]} ({mat[2]}) - 총길이: {total_length}mm, 총개수: {total_count}개, 평균: {total_length/total_count:.1f}mm")
|
||||
else:
|
||||
# 첫 파이프 정보 설정
|
||||
pipe_length = float(mat[4]) * float(mat[7])
|
||||
existing["pipe_details"] = {
|
||||
"length_mm": float(mat[7]),
|
||||
"total_length_mm": pipe_length,
|
||||
"pipe_count": float(mat[4])
|
||||
}
|
||||
else:
|
||||
# 🆕 새 항목 생성
|
||||
material_data = {
|
||||
"material_hash": material_hash,
|
||||
"description": mat[1], # original_description
|
||||
"size_spec": mat[2],
|
||||
"material_grade": mat[3],
|
||||
"quantity": float(mat[4]) if mat[4] else 0.0,
|
||||
"category": mat[5], # classified_category
|
||||
"unit": mat[6] or 'EA',
|
||||
"line_number": str(mat[8]) if mat[8] else ''
|
||||
}
|
||||
|
||||
# 파이프인 경우 pipe_details 정보 추가
|
||||
if mat[5] == 'PIPE' and mat[7] is not None:
|
||||
pipe_length = float(mat[4]) * float(mat[7]) # 수량 × 단위길이
|
||||
material_data["pipe_details"] = {
|
||||
"length_mm": float(mat[7]), # 단위 길이
|
||||
"total_length_mm": pipe_length, # 총 길이
|
||||
"pipe_count": float(mat[4]) # 파이프 개수
|
||||
}
|
||||
print(f"🆕 파이프 신규: {mat[1]} ({mat[2]}) - 단위: {mat[7]}mm, 총길이: {pipe_length}mm")
|
||||
|
||||
materials_dict[material_hash] = material_data
|
||||
|
||||
# 파이프 데이터가 포함되었는지 확인
|
||||
pipe_count = sum(1 for data in materials_dict.values() if data.get('category') == 'PIPE')
|
||||
pipe_with_details = sum(1 for data in materials_dict.values()
|
||||
if data.get('category') == 'PIPE' and 'pipe_details' in data)
|
||||
print(f"🔍 반환 결과: 총 {len(materials_dict)}개 자재, 파이프 {pipe_count}개, pipe_details 있는 파이프 {pipe_with_details}개")
|
||||
|
||||
# 첫 번째 파이프 데이터 샘플 출력
|
||||
for hash_key, data in materials_dict.items():
|
||||
if data.get('category') == 'PIPE':
|
||||
print(f"🔍 파이프 샘플: {data}")
|
||||
break
|
||||
|
||||
return materials_dict
|
||||
|
||||
|
||||
Reference in New Issue
Block a user