114 lines
3.6 KiB
Python
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}")
|