#!/usr/bin/env python3
"""
Robust employee import with comprehensive field mapping and error handling
"""
import csv
import sys
import os
import time
from datetime import datetime
# Add the src directory to Python path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src'))
from odoo_mcp.odoo_client import get_odoo_client
from csv_to_odoo_field_mapping import map_csv_row_to_odoo_employee
def safe_create_employee(client, employee_data, employee_name):
"""Safely create employee with error handling and field validation"""
try:
# Start with core required fields only
core_fields = ['name']
core_data = {field: employee_data[field] for field in core_fields if field in employee_data}
# Add safe optional fields
safe_fields = [
'work_phone', 'work_email', 'private_city', 'identification_id',
'birthday', 'first_contract_date', 'job_title', 'passport_id',
'driving_license', 'license_plate', 'vehicle', 'private_car_plate'
]
for field in safe_fields:
if field in employee_data and employee_data[field]:
core_data[field] = employee_data[field]
# Handle department separately
if 'department_id' in employee_data:
try:
dept_id = int(employee_data['department_id'])
core_data['department_id'] = dept_id
except (ValueError, TypeError):
pass # Skip invalid department ID
# Handle country separately
if 'country_of_birth' in employee_data:
try:
country_id = int(employee_data['country_of_birth'])
core_data['country_of_birth'] = country_id
except (ValueError, TypeError):
pass # Skip invalid country ID
# Add notes for remaining fields
notes_fields = []
for field, value in employee_data.items():
if field not in core_data and field != 'notes' and value:
notes_fields.append(f"{field}: {value}")
if employee_data.get('notes'):
notes_fields.append(employee_data['notes'])
if notes_fields:
core_data['notes'] = '\n'.join(notes_fields)
print(f" Creating with {len(core_data)} fields")
result = client.create_record('hr.employee', core_data)
if isinstance(result, list) and len(result) > 0:
return result[0]
else:
print(f" Create failed: {result}")
return None
except Exception as e:
print(f" Error creating {employee_name}: {str(e)}")
return None
def robust_import():
"""Execute robust employee import"""
csv_file = '/Users/ramizmohamed/Downloads/Asset Managment - COURIER MASTER SHEET (1).csv'
try:
print("=== ROBUST EMPLOYEE IMPORT ===")
print()
# Initialize
client = get_odoo_client()
print("✓ Connected to Odoo")
# Get existing employees
existing = client.search_read('hr.employee', [], ['name'])
existing_names = set(emp['name'] for emp in existing)
print(f"✓ Found {len(existing_names)} existing employees")
# Process CSV
created = 0
failed = 0
skipped = 0
with open(csv_file, 'r', encoding='utf-8') as file:
reader = csv.DictReader(file)
for row_num, row in enumerate(reader, start=2):
if row['Status'].strip().lower() != 'active':
continue
name = row['Name'].strip()
if name in existing_names:
print(f"Row {row_num}: Skip {name} (exists)")
skipped += 1
continue
print(f"Row {row_num}: {name}")
# Map fields
try:
employee_data = map_csv_row_to_odoo_employee(row)
# Safe create
emp_id = safe_create_employee(client, employee_data, name)
if emp_id:
created += 1
existing_names.add(name)
print(f" ✓ Created ID: {emp_id}")
else:
failed += 1
print(f" ✗ Failed")
except Exception as e:
failed += 1
print(f" ✗ Mapping error: {str(e)}")
# Progress update
total_processed = created + failed + skipped
if total_processed % 25 == 0:
print(f"\n--- Progress: Created {created}, Failed {failed}, Skipped {skipped} ---\n")
time.sleep(1) # Brief pause
print(f"\n=== FINAL RESULTS ===")
print(f"✓ Created: {created}")
print(f"✗ Failed: {failed}")
print(f"⚠ Skipped: {skipped}")
print(f"📊 Total: {created + failed + skipped}")
except Exception as e:
print(f"Error: {str(e)}")
import traceback
traceback.print_exc()
if __name__ == '__main__':
robust_import()