bmc_hub/scripts/import_vendors_from_omnisync.py
Christian 3a35042788 feat: Implement Vendors API and Frontend
- Added a new API router for managing vendors with endpoints for listing, creating, updating, retrieving, and deleting vendors.
- Implemented frontend views for displaying vendor lists and details using Jinja2 templates.
- Created HTML templates for vendor list and detail pages with responsive design and dynamic content loading.
- Added JavaScript functionality for vendor management, including pagination, filtering, and modal forms for creating new vendors.
- Introduced a settings table in the database for system configuration and extended the users table with additional fields.
- Developed a script to import vendors from an OmniSync database into the PostgreSQL database, handling errors and logging progress.
2025-12-06 11:04:19 +01:00

114 lines
3.6 KiB
Python

"""
Import vendors from OmniSync database
"""
import psycopg2
from psycopg2.extras import RealDictCursor
import sqlite3
import os
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
OMNISYNC_DB = '/omnisync_data/fakturering.db'
def get_postgres_connection():
"""Get PostgreSQL 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 get_sqlite_connection():
"""Get SQLite connection to OmniSync database"""
return sqlite3.connect(OMNISYNC_DB)
def import_vendors():
"""Import vendors from OmniSync"""
sqlite_conn = get_sqlite_connection()
sqlite_cursor = sqlite_conn.cursor()
imported = 0
skipped = 0
errors = []
try:
# Get vendors from OmniSync
sqlite_cursor.execute("""
SELECT
name, domain, email_pattern, category, priority, notes, created_at
FROM vendors
WHERE deleted_at IS NULL
ORDER BY name
""")
vendors = sqlite_cursor.fetchall()
logger.info(f"📥 Found {len(vendors)} active vendors in OmniSync")
for row in vendors:
name, domain, email_pattern, category, priority, notes, created_at = row
# Skip if no name
if not name or name.strip() == '':
skipped += 1
continue
# Individual connection per vendor
postgres_conn = get_postgres_connection()
postgres_cursor = postgres_conn.cursor()
try:
postgres_cursor.execute("""
INSERT INTO vendors (
name, domain, email_pattern, category, priority, notes, is_active, created_at
) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
ON CONFLICT (cvr_number) DO NOTHING
RETURNING id
""", (
name, domain, email_pattern, category or 'general',
priority or 50, notes, True, created_at
))
result = postgres_cursor.fetchone()
postgres_conn.commit()
if result:
imported += 1
if imported % 10 == 0:
logger.info(f" Imported {imported} vendors...")
except Exception as e:
error_msg = str(e)[:100]
if imported + skipped < 10:
logger.warning(f" ⚠️ Could not import '{name}': {error_msg}")
errors.append((name, error_msg))
skipped += 1
finally:
postgres_cursor.close()
postgres_conn.close()
logger.info(f"✅ Vendors: {imported} imported, {skipped} skipped")
if len(errors) > 10:
logger.info(f" (Suppressed {len(errors)-10} error messages)")
return imported
except Exception as e:
logger.error(f"❌ Vendor import failed: {e}")
raise
finally:
sqlite_cursor.close()
sqlite_conn.close()
if __name__ == "__main__":
logger.info("🚀 Starting vendor import from OmniSync...")
logger.info(f"📂 Source: {OMNISYNC_DB}")
vendor_count = import_vendors()
logger.info(f"\n🎉 Import completed!")
logger.info(f" Vendors: {vendor_count}")