#!/usr/bin/env python3 """ 구매 수량 계산기 테스트 특히 파이프 절단 손실 + 6M 단위 계산 테스트 """ import sys import os sys.path.append('backend') def test_pipe_calculation(): """파이프 절단 손실 + 6M 단위 계산 테스트""" from app.services.purchase_calculator import calculate_pipe_purchase_quantity print("🔧 PIPE 구매 수량 계산 테스트\n") # 테스트 케이스들 test_cases = [ { "name": "25,000mm 필요 (10회 절단)", "materials": [ {"length_mm": 3000, "original_description": "PIPE 4\" SCH40 - 3M", "quantity": 1}, {"length_mm": 2500, "original_description": "PIPE 4\" SCH40 - 2.5M", "quantity": 1}, {"length_mm": 1800, "original_description": "PIPE 4\" SCH40 - 1.8M", "quantity": 1}, {"length_mm": 4200, "original_description": "PIPE 4\" SCH40 - 4.2M", "quantity": 1}, {"length_mm": 2100, "original_description": "PIPE 4\" SCH40 - 2.1M", "quantity": 1}, {"length_mm": 1500, "original_description": "PIPE 4\" SCH40 - 1.5M", "quantity": 1}, {"length_mm": 3800, "original_description": "PIPE 4\" SCH40 - 3.8M", "quantity": 1}, {"length_mm": 2200, "original_description": "PIPE 4\" SCH40 - 2.2M", "quantity": 1}, {"length_mm": 1900, "original_description": "PIPE 4\" SCH40 - 1.9M", "quantity": 1}, {"length_mm": 2000, "original_description": "PIPE 4\" SCH40 - 2M", "quantity": 1} ], "expected_pipes": 5 }, { "name": "5,900mm 필요 (3회 절단)", "materials": [ {"length_mm": 2000, "original_description": "PIPE 6\" SCH40 - 2M", "quantity": 1}, {"length_mm": 1900, "original_description": "PIPE 6\" SCH40 - 1.9M", "quantity": 1}, {"length_mm": 2000, "original_description": "PIPE 6\" SCH40 - 2M", "quantity": 1} ], "expected_pipes": 1 }, { "name": "12,000mm 정확히 (4회 절단)", "materials": [ {"length_mm": 3000, "original_description": "PIPE 8\" SCH40 - 3M", "quantity": 4} ], "expected_pipes": 2 } ] for i, test_case in enumerate(test_cases, 1): print(f"📋 테스트 {i}: {test_case['name']}") result = calculate_pipe_purchase_quantity(test_case["materials"]) print(f" 🎯 BOM 총 길이: {result['bom_quantity']:,}mm") print(f" ✂️ 절단 횟수: {result['cutting_count']}회") print(f" 📏 절단 손실: {result['cutting_loss']}mm (각 절단마다 3mm)") print(f" 🔢 총 필요량: {result['required_length']:,}mm") print(f" 📦 구매 파이프: {result['pipes_count']}본 (각 6M)") print(f" 💰 구매 총량: {result['calculated_qty']:,}mm") print(f" ♻️ 여유분: {result['waste_length']:,}mm") print(f" 📊 활용률: {result['utilization_rate']:.1f}%") # 결과 확인 if result['pipes_count'] == test_case['expected_pipes']: print(f" ✅ 성공: 예상 {test_case['expected_pipes']}본 = 결과 {result['pipes_count']}본") else: print(f" ❌ 실패: 예상 {test_case['expected_pipes']}본 ≠ 결과 {result['pipes_count']}본") print() def test_standard_calculation(): """일반 자재 구매 수량 계산 테스트""" from app.services.purchase_calculator import calculate_standard_purchase_quantity print("🔧 일반 자재 구매 수량 계산 테스트\n") test_cases = [ {"category": "VALVE", "bom_qty": 2, "expected_factor": 1.5, "desc": "밸브 2개 (50% 예비품)"}, {"category": "BOLT", "bom_qty": 24, "expected_min": 50, "desc": "볼트 24개 (박스 단위 50개)"}, {"category": "FITTING", "bom_qty": 5, "expected_factor": 1.1, "desc": "피팅 5개 (10% 여유)"}, {"category": "GASKET", "bom_qty": 3, "expected_factor": 1.25, "desc": "가스켓 3개 (25% 교체 주기)"}, {"category": "INSTRUMENT", "bom_qty": 1, "expected_factor": 1.0, "desc": "계기 1개 (정확한 수량)"} ] for i, test_case in enumerate(test_cases, 1): print(f"📋 테스트 {i}: {test_case['desc']}") result = calculate_standard_purchase_quantity( test_case["category"], test_case["bom_qty"] ) print(f" 🎯 BOM 수량: {result['bom_quantity']}") print(f" 📈 여유율: {result['safety_factor']:.2f} ({(result['safety_factor']-1)*100:.0f}%)") print(f" 🔢 여유 적용: {result['safety_qty']:.1f}") print(f" 📦 최소 주문: {result['min_order_qty']}") print(f" 💰 최종 구매: {result['calculated_qty']}") print(f" ♻️ 여유분: {result['waste_quantity']}") print(f" 📊 활용률: {result['utilization_rate']:.1f}%") print() if __name__ == "__main__": test_pipe_calculation() test_standard_calculation()