233 lines
8.4 KiB
Python
233 lines
8.4 KiB
Python
|
|
"""
|
||
|
|
Data import script for BMC Hub
|
||
|
|
Imports customers and contacts from CSV files or creates sample data
|
||
|
|
"""
|
||
|
|
|
||
|
|
import psycopg2
|
||
|
|
from psycopg2.extras import RealDictCursor
|
||
|
|
import os
|
||
|
|
import logging
|
||
|
|
|
||
|
|
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||
|
|
logger = logging.getLogger(__name__)
|
||
|
|
|
||
|
|
|
||
|
|
def get_connection():
|
||
|
|
"""Get database connection"""
|
||
|
|
database_url = os.getenv('DATABASE_URL', 'postgresql://bmc_hub:bmc_hub@postgres:5432/bmc_hub')
|
||
|
|
return psycopg2.connect(database_url, cursor_factory=RealDictCursor)
|
||
|
|
|
||
|
|
|
||
|
|
def import_sample_data():
|
||
|
|
"""Import sample customers and contacts for testing"""
|
||
|
|
conn = get_connection()
|
||
|
|
cursor = conn.cursor()
|
||
|
|
|
||
|
|
try:
|
||
|
|
# Sample customers
|
||
|
|
customers = [
|
||
|
|
{
|
||
|
|
'name': 'TDC A/S',
|
||
|
|
'cvr_number': '14773908',
|
||
|
|
'address': 'Teglholmsgade 1',
|
||
|
|
'postal_code': '2450',
|
||
|
|
'city': 'København SV',
|
||
|
|
'email': 'info@tdc.dk',
|
||
|
|
'phone': '+45 70 70 40 30',
|
||
|
|
'website': 'https://tdc.dk',
|
||
|
|
'is_active': True
|
||
|
|
},
|
||
|
|
{
|
||
|
|
'name': 'Dansk Supermarked Group',
|
||
|
|
'cvr_number': '16314439',
|
||
|
|
'address': 'Roskildevej 65',
|
||
|
|
'postal_code': '2620',
|
||
|
|
'city': 'Albertslund',
|
||
|
|
'email': 'info@dsg.dk',
|
||
|
|
'phone': '+45 43 86 43 86',
|
||
|
|
'website': 'https://dansksupermarked.dk',
|
||
|
|
'is_active': True
|
||
|
|
},
|
||
|
|
{
|
||
|
|
'name': 'Nets Denmark A/S',
|
||
|
|
'cvr_number': '20016175',
|
||
|
|
'address': 'Lautrupbjerg 10',
|
||
|
|
'postal_code': '2750',
|
||
|
|
'city': 'Ballerup',
|
||
|
|
'email': 'info@nets.eu',
|
||
|
|
'phone': '+45 44 68 44 68',
|
||
|
|
'website': 'https://nets.eu',
|
||
|
|
'is_active': True
|
||
|
|
},
|
||
|
|
{
|
||
|
|
'name': 'Salling Group',
|
||
|
|
'cvr_number': '30521736',
|
||
|
|
'address': 'Skanderborgvej 121',
|
||
|
|
'postal_code': '8260',
|
||
|
|
'city': 'Viby J',
|
||
|
|
'email': 'info@sallinggroup.com',
|
||
|
|
'phone': '+45 87 93 35 00',
|
||
|
|
'website': 'https://sallinggroup.com',
|
||
|
|
'is_active': True
|
||
|
|
},
|
||
|
|
{
|
||
|
|
'name': 'ISS A/S',
|
||
|
|
'cvr_number': '28861341',
|
||
|
|
'address': 'Buddingevej 197',
|
||
|
|
'postal_code': '2860',
|
||
|
|
'city': 'Søborg',
|
||
|
|
'email': 'info@dk.issworld.com',
|
||
|
|
'phone': '+45 38 17 00 00',
|
||
|
|
'website': 'https://issworld.com',
|
||
|
|
'is_active': True
|
||
|
|
}
|
||
|
|
]
|
||
|
|
|
||
|
|
logger.info("Importing customers...")
|
||
|
|
customer_ids = {}
|
||
|
|
|
||
|
|
for customer in customers:
|
||
|
|
cursor.execute("""
|
||
|
|
INSERT INTO customers (
|
||
|
|
name, cvr_number, address, postal_code, city,
|
||
|
|
email, phone, website, is_active
|
||
|
|
) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)
|
||
|
|
RETURNING id
|
||
|
|
""", (
|
||
|
|
customer['name'], customer['cvr_number'], customer['address'],
|
||
|
|
customer['postal_code'], customer['city'], customer['email'],
|
||
|
|
customer['phone'], customer['website'], customer['is_active']
|
||
|
|
))
|
||
|
|
result = cursor.fetchone()
|
||
|
|
customer_id = result['id']
|
||
|
|
customer_ids[customer['name']] = customer_id
|
||
|
|
logger.info(f"✅ Imported customer: {customer['name']} (ID: {customer_id})")
|
||
|
|
|
||
|
|
# Sample contacts
|
||
|
|
contacts = [
|
||
|
|
{
|
||
|
|
'first_name': 'Lars',
|
||
|
|
'last_name': 'Jensen',
|
||
|
|
'email': 'lars.jensen@tdc.dk',
|
||
|
|
'phone': '+45 70 70 40 31',
|
||
|
|
'mobile': '+45 20 12 34 56',
|
||
|
|
'title': 'CTO',
|
||
|
|
'department': 'IT',
|
||
|
|
'companies': ['TDC A/S'],
|
||
|
|
'is_primary': True,
|
||
|
|
'role': 'Teknisk kontakt'
|
||
|
|
},
|
||
|
|
{
|
||
|
|
'first_name': 'Mette',
|
||
|
|
'last_name': 'Nielsen',
|
||
|
|
'email': 'mette.nielsen@dsg.dk',
|
||
|
|
'phone': '+45 43 86 43 87',
|
||
|
|
'mobile': '+45 30 98 76 54',
|
||
|
|
'title': 'IT Manager',
|
||
|
|
'department': 'IT Operations',
|
||
|
|
'companies': ['Dansk Supermarked Group'],
|
||
|
|
'is_primary': True,
|
||
|
|
'role': 'Primær kontakt'
|
||
|
|
},
|
||
|
|
{
|
||
|
|
'first_name': 'Peter',
|
||
|
|
'last_name': 'Hansen',
|
||
|
|
'email': 'peter.hansen@nets.eu',
|
||
|
|
'phone': '+45 44 68 44 69',
|
||
|
|
'mobile': '+45 40 11 22 33',
|
||
|
|
'title': 'Network Engineer',
|
||
|
|
'department': 'Infrastructure',
|
||
|
|
'companies': ['Nets Denmark A/S'],
|
||
|
|
'is_primary': True,
|
||
|
|
'role': 'Teknisk ansvarlig'
|
||
|
|
},
|
||
|
|
{
|
||
|
|
'first_name': 'Anne',
|
||
|
|
'last_name': 'Andersen',
|
||
|
|
'email': 'anne.andersen@sallinggroup.com',
|
||
|
|
'phone': '+45 87 93 35 01',
|
||
|
|
'mobile': '+45 50 44 55 66',
|
||
|
|
'title': 'IT Director',
|
||
|
|
'department': 'IT',
|
||
|
|
'companies': ['Salling Group'],
|
||
|
|
'is_primary': True,
|
||
|
|
'role': 'Beslutningsansvarlig'
|
||
|
|
},
|
||
|
|
{
|
||
|
|
'first_name': 'Thomas',
|
||
|
|
'last_name': 'Christensen',
|
||
|
|
'email': 'thomas.christensen@issworld.com',
|
||
|
|
'phone': '+45 38 17 00 01',
|
||
|
|
'mobile': '+45 60 77 88 99',
|
||
|
|
'title': 'Senior IT Consultant',
|
||
|
|
'department': 'IT Services',
|
||
|
|
'companies': ['ISS A/S', 'Nets Denmark A/S'], # Multi-company contact
|
||
|
|
'is_primary': False,
|
||
|
|
'role': 'Konsulent'
|
||
|
|
}
|
||
|
|
]
|
||
|
|
|
||
|
|
logger.info("Importing contacts...")
|
||
|
|
|
||
|
|
for contact in contacts:
|
||
|
|
# Insert contact
|
||
|
|
cursor.execute("""
|
||
|
|
INSERT INTO contacts (
|
||
|
|
first_name, last_name, email, phone, mobile,
|
||
|
|
title, department, is_active
|
||
|
|
) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
|
||
|
|
RETURNING id
|
||
|
|
""", (
|
||
|
|
contact['first_name'], contact['last_name'], contact['email'],
|
||
|
|
contact['phone'], contact['mobile'], contact['title'],
|
||
|
|
contact['department'], True
|
||
|
|
))
|
||
|
|
result = cursor.fetchone()
|
||
|
|
contact_id = result['id']
|
||
|
|
|
||
|
|
# Link to companies
|
||
|
|
for company_name in contact['companies']:
|
||
|
|
if company_name in customer_ids:
|
||
|
|
cursor.execute("""
|
||
|
|
INSERT INTO contact_companies (
|
||
|
|
contact_id, customer_id, is_primary, role
|
||
|
|
) VALUES (%s, %s, %s, %s)
|
||
|
|
""", (
|
||
|
|
contact_id, customer_ids[company_name],
|
||
|
|
contact['is_primary'] if contact['companies'][0] == company_name else False,
|
||
|
|
contact['role']
|
||
|
|
))
|
||
|
|
|
||
|
|
logger.info(f"✅ Imported contact: {contact['first_name']} {contact['last_name']} (ID: {contact_id}, Companies: {len(contact['companies'])})")
|
||
|
|
|
||
|
|
conn.commit()
|
||
|
|
logger.info("🎉 Sample data import completed successfully!")
|
||
|
|
|
||
|
|
# Print summary
|
||
|
|
cursor.execute("SELECT COUNT(*) as count FROM customers")
|
||
|
|
customer_count = cursor.fetchone()['count']
|
||
|
|
|
||
|
|
cursor.execute("SELECT COUNT(*) as count FROM contacts")
|
||
|
|
contact_count = cursor.fetchone()['count']
|
||
|
|
|
||
|
|
cursor.execute("SELECT COUNT(*) as count FROM contact_companies")
|
||
|
|
link_count = cursor.fetchone()['count']
|
||
|
|
|
||
|
|
logger.info(f"\n📊 Summary:")
|
||
|
|
logger.info(f" Customers: {customer_count}")
|
||
|
|
logger.info(f" Contacts: {contact_count}")
|
||
|
|
logger.info(f" Company-Contact Links: {link_count}")
|
||
|
|
|
||
|
|
except Exception as e:
|
||
|
|
conn.rollback()
|
||
|
|
logger.error(f"❌ Import failed: {e}")
|
||
|
|
raise
|
||
|
|
finally:
|
||
|
|
cursor.close()
|
||
|
|
conn.close()
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
logger.info("🚀 Starting data import...")
|
||
|
|
import_sample_data()
|