Files
tilbudgivern/tests/test_roesevangen_ordrestyring.py
alexpolo1 26d3452d59 Add comprehensive tests for API verification, frontend integration, and PDF generation
- Implemented a new test suite for production API verification using curl, ensuring all critical endpoints respond correctly and return valid JSON.
- Added frontend integration tests to check for critical errors in the UI and verify key UI elements are present and functional.
- Created test data for quotes and project calculations to facilitate testing.
- Developed a script to check offers in the Ordrestyring system, including detailed task descriptions.
- Added tests for generating PDFs from quote data, ensuring the output is valid and contains expected information.
- Implemented a test script for the Røsevangen project, integrating with the Ordrestyring API and verifying database entries.
2025-11-07 08:02:07 +00:00

340 lines
12 KiB
Python

#!/usr/bin/env python3
"""
Test script: Generer tilbud for Røsevangen 44 og send til Ordrestyring
"""
import mysql.connector
import requests
import json
from datetime import datetime
# Database connection
db_config = {
'host': 'localhost',
'user': 'tilbuduser',
'password': 'tilbudpass123',
'database': 'tilbudgivern'
}
# Projekt data
PROJECT_ID = 22 # Komplet tagudskiftning - Røsevangen 44
# Brug EKSISTERENDE kunde fra Ordrestyring (må IKKE oprette ny!)
CUSTOMER_ID = 5355 # Alexander Warme (eksisterende kunde)
def insert_project_data():
"""Indsætter projekt data i databasen"""
conn = mysql.connector.connect(**db_config)
cursor = conn.cursor()
try:
# Check om projekt eksisterer
cursor.execute("SELECT id FROM customer_projects WHERE id = %s", (PROJECT_ID,))
if not cursor.fetchone():
print(f"❌ Projekt ID {PROJECT_ID} findes ikke i databasen")
return False
print(f"✅ Bruger eksisterende projekt ID {PROJECT_ID}")
# Indsæt geometri
cursor.execute("""
INSERT INTO roof_geometry (project_id, total_area, roof_pitch, roof_height, roof_type)
VALUES (%s, %s, %s, %s, %s)
ON DUPLICATE KEY UPDATE
total_area = VALUES(total_area),
roof_pitch = VALUES(roof_pitch),
roof_height = VALUES(roof_height),
roof_type = VALUES(roof_type)
""", (PROJECT_ID, 105.0, 35, 6.5, 'skraat_tag'))
# Indsæt arbejdstimer
labor_cost_total = 85.5 * 580.0
cursor.execute("""
INSERT INTO project_labor (project_id, total_work_hours, carpenter_count, hourly_rate, estimated_hours_per_carpenter, total_labor_cost)
VALUES (%s, %s, %s, %s, %s, %s)
ON DUPLICATE KEY UPDATE
total_work_hours = VALUES(total_work_hours),
carpenter_count = VALUES(carpenter_count),
hourly_rate = VALUES(hourly_rate),
estimated_hours_per_carpenter = VALUES(estimated_hours_per_carpenter),
total_labor_cost = VALUES(total_labor_cost)
""", (PROJECT_ID, 85.5, 2, 580.0, 42.75, labor_cost_total))
# Beregn priser
labor_cost = 85.5 * 580.0 # 49,590.00 kr
material_cost = 66503.00 # Fra materialer
subtotal = labor_cost + material_cost
overhead = subtotal * 0.15
profit = subtotal * 0.20
total_excl_vat = subtotal + overhead + profit
vat = total_excl_vat * 0.25
total_incl_vat = total_excl_vat + vat
# Indsæt beregning
# Først slet eksisterende
cursor.execute("DELETE FROM project_calculations WHERE project_id = %s", (PROJECT_ID,))
# Derefter indsæt ny
cursor.execute("""
INSERT INTO project_calculations
(project_id, total_area, total_work_hours, carpenter_count,
total_labor_cost, total_material_cost, material_count,
subtotal, overhead_percentage, overhead_amount,
profit_percentage, profit_amount, total_excl_vat,
vat_percentage, vat_amount, total_incl_vat)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
""", (PROJECT_ID, 105.0, 85.5, 2,
labor_cost, material_cost, 10,
subtotal, 15.0, overhead,
20.0, profit, total_excl_vat,
25.0, vat, total_incl_vat))
calculation_id = cursor.lastrowid
if calculation_id == 0:
# Hent existing calculation ID
cursor.execute("SELECT id FROM project_calculations WHERE project_id = %s ORDER BY created_at DESC LIMIT 1", (PROJECT_ID,))
result = cursor.fetchone()
calculation_id = result[0] if result else None
# Indsæt materialer
materials = [
('Eternit B7 tagplader 920x1320mm', 223, 'stk', 245.00),
('Lindab Rainline tagrende 125mm 3m', 14, 'stk', 245.00),
('Lindab Rainline konsoljern', 67, 'stk', 28.00),
('Lindab nedløb 3m', 4, 'stk', 185.00),
('Eternit tagskruer 400 stk', 2, 'pakke', 385.00),
('Lægte 30x50mm trykimp', 228, 'lbm', 18.50),
('Spær træ 45x200mm', 96, 'lbm', 42.00),
('EPDM tætningsbånd 30m', 8, 'rulle', 285.00),
('Eternit rygning B7', 12, 'lbm', 125.00),
('Ringsøm 2.8x65mm 2880 stk', 2, 'pakke', 145.00)
]
# Slet gamle materialer for dette projekt
cursor.execute("DELETE FROM project_materials WHERE project_id = %s", (PROJECT_ID,))
for material_name, quantity, unit, unit_price in materials:
total_price = quantity * unit_price
cursor.execute("""
INSERT INTO project_materials
(project_id, material_name, quantity, unit, unit_price, total_price, material_category)
VALUES (%s, %s, %s, %s, %s, %s, %s)
""", (PROJECT_ID, material_name, quantity, unit, unit_price, total_price, 'Tagmaterialer'))
# Opret generated_quotes entry hvis ikke eksisterer
cursor.execute("""
INSERT INTO generated_quotes (project_id, calculation_id, quote_text, created_at)
VALUES (%s, %s, %s, NOW())
ON DUPLICATE KEY UPDATE calculation_id = VALUES(calculation_id), quote_text = VALUES(quote_text)
""", (PROJECT_ID, calculation_id, 'Tilbud genereret via test script'))
conn.commit()
print("✅ Projekt data indsat i database")
print(f" Project ID: {PROJECT_ID}")
print(f" Calculation ID: {calculation_id}")
print(f" Arbejdsløn: {labor_cost:,.2f} kr")
print(f" Materialer: {material_cost:,.2f} kr")
print(f" Antal materialer: {len(materials)}")
return calculation_id
except Exception as e:
print(f"❌ Fejl ved indsættelse af data: {e}")
import traceback
traceback.print_exc()
conn.rollback()
return None
finally:
cursor.close()
conn.close()
def test_preview():
"""Test preview af tilbudsbeskrivelse"""
print("\n" + "=" * 80)
print("TEST 1: Preview tilbudsbeskrivelse")
print("=" * 80)
# Hent calculation_id fra database
conn = mysql.connector.connect(**db_config)
cursor = conn.cursor()
cursor.execute("SELECT id FROM project_calculations WHERE project_id = %s ORDER BY created_at DESC LIMIT 1", (PROJECT_ID,))
result = cursor.fetchone()
calculation_id = result[0] if result else 1
cursor.close()
conn.close()
response = requests.post(
'http://localhost:4031/api/ordrestyring/preview-description',
json={
'projectId': PROJECT_ID,
'calculationId': calculation_id
}
)
if response.status_code == 200:
data = response.json()
if data.get('success'):
print("\n✅ Beskrivelse genereret!\n")
print("KUNDE BESKRIVELSE (første 500 tegn):")
print("-" * 80)
print(data['description'][:500] + "...")
print("-" * 80)
if 'internalNotes' in data:
print("\nINTERNE NOTER (første 300 tegn):")
print("-" * 80)
print(data['internalNotes'][:300] + "...")
print("-" * 80)
print(f"\n💰 Pris eks. moms: {data['priceExVat']:,.2f} kr")
print(f"💰 Pris inkl. moms: {data['priceInclVat']:,.2f} kr")
return True
else:
print(f"❌ Fejl: {data.get('error')}")
return False
else:
print(f"❌ HTTP fejl {response.status_code}")
print(response.text)
return False
def send_to_ordrestyring():
"""Send tilbud til Ordrestyring"""
print("\n" + "=" * 80)
print("TEST 2: Send tilbud til Ordrestyring")
print("=" * 80)
confirm = input("\n📤 Vil du sende tilbuddet til Ordrestyring? (y/n): ")
if confirm.lower() != 'y':
print("⏹️ Test afbrudt")
return None
# Hent calculation_id fra database
conn = mysql.connector.connect(**db_config)
cursor = conn.cursor()
cursor.execute("SELECT id FROM project_calculations WHERE project_id = %s ORDER BY created_at DESC LIMIT 1", (PROJECT_ID,))
result = cursor.fetchone()
calculation_id = result[0] if result else 1
cursor.close()
conn.close()
response = requests.post(
'http://localhost:4031/api/ordrestyring/send-quote-graphql',
json={
'projectId': PROJECT_ID,
'calculationId': calculation_id,
'customerId': CUSTOMER_ID # Brug eksisterende kunde ID 5355
}
)
if response.status_code == 200:
data = response.json()
if data.get('success'):
offer = data['offer']
print("\n✅ Tilbud sendt til Ordrestyring!\n")
print("=" * 80)
print(f"Offer ID: {offer['id']}")
print(f"Offer Number: {offer['number']}")
print(f"Customer: {offer['customer']['name']}")
print(f"Status: {offer['status']['text']}")
print(f"Price ex VAT: {offer['totals']['salesPrice']:,.2f} kr")
print(f"Price incl VAT: {offer['totals']['salesPriceWithVat']:,.2f} kr")
print(f"Created: {offer['createdAt']}")
print("=" * 80)
return offer['id']
else:
print(f"❌ Fejl: {data.get('error')}")
return None
else:
print(f"❌ HTTP fejl {response.status_code}")
print(response.text)
return None
def verify_in_database(offer_id):
"""Verificer at tilbud er gemt i database"""
if not offer_id:
return
print("\n" + "=" * 80)
print("TEST 3: Verificer i database")
print("=" * 80)
conn = mysql.connector.connect(**db_config)
cursor = conn.cursor(dictionary=True)
try:
cursor.execute("""
SELECT
id,
project_id,
ordrestyring_offer_id,
ordrestyring_offer_number,
ordrestyring_status,
ordrestyring_sent_at
FROM generated_quotes
WHERE ordrestyring_offer_id = %s
""", (offer_id,))
result = cursor.fetchone()
if result:
print("\n✅ Tilbud fundet i database!\n")
for key, value in result.items():
print(f"{key}: {value}")
else:
print(f"❌ Tilbud med offer_id {offer_id} ikke fundet i database")
except Exception as e:
print(f"❌ Database fejl: {e}")
finally:
cursor.close()
conn.close()
def main():
print("\n" + "=" * 80)
print(" RØSEVANGEN 44 - ORDRESTYRING INTEGRATION TEST")
print("=" * 80)
print(f"\nProjekt: Komplet tagudskiftning - Røsevangen 44")
print(f"Kunde: Alexander Warme (ID: {CUSTOMER_ID})")
print(f"Projekt ID: {PROJECT_ID}")
# Step 1: Indsæt data
print("\n" + "-" * 80)
print("STEP 1: Indsæt projekt data i database")
print("-" * 80)
calculation_id = insert_project_data()
if not calculation_id:
print("❌ Kunne ikke indsætte data - afbryder")
return
# Step 2: Preview
if not test_preview():
print("❌ Preview fejlede - afbryder")
return
# Step 3: Send til Ordrestyring
offer_id = send_to_ordrestyring()
# Step 4: Verificer i database
if offer_id:
verify_in_database(offer_id)
print("\n" + "=" * 80)
print("✅ TEST FÆRDIG!")
print("=" * 80)
print("\nNæste skridt:")
print(" 1. Check tilbuddet i Ordrestyring systemet")
print(" 2. Verificer at status er 'Tilbudsgiver Oprettet Tilbud'")
print(" 3. Åbn 'Noter' og check at interne beregninger er der")
print(" 4. Verificer at kunde-beskrivelse IKKE viser overhead/fortjeneste")
print("=" * 80 + "\n")
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
print("\n\n⏹️ Test afbrudt af bruger")
except Exception as e:
print(f"\n❌ Uventet fejl: {e}")
import traceback
traceback.print_exc()