from proteus import config, Model
import psycopg2

# XML-RPC Configuration (default connection method)
HTTPS = 'https://'
SERVER_URL = 'itsa.open-squared.tech'
DATABASE_NAME = 'tradon'
USERNAME = 'admin'
PASSWORD = 'dsproject'

# PostgreSQL Configuration (for direct database inspection)
DB_HOST = '72.61.163.139'
DB_PORT = 5433
DB_USER = 'postgres'
DB_PASSWORD = 'dsproject'

print("="*80)
print("CUSTOM FIELDS IDENTIFICATION FOR purchase.purchase")
print("="*80)

# Connect to Tryton via XML-RPC
print(f"\nConnecting via XML-RPC to {SERVER_URL}...")
config.set_xmlrpc(f'{HTTPS}{USERNAME}:{PASSWORD}@{SERVER_URL}/{DATABASE_NAME}/')
print("✓ Connected successfully\n")

Purchase = Model.get('purchase.purchase')

# Get all fields that Proteus sees
proteus_fields = sorted([key for key in dir(Purchase) 
                        if not key.startswith('_') 
                        and key not in ['create', 'delete', 'save', 'find', 
                                       'copy', 'read', 'write', 'search']])

print(f"1. FIELDS VISIBLE TO PROTEUS: {len(proteus_fields)} fields")
print("-"*80)

# Standard Tryton purchase.purchase fields (from base module)
standard_purchase_fields = {
    'id', 'create_date', 'create_uid', 'write_date', 'write_uid',
    'company', 'party', 'invoice_party', 'invoice_address', 
    'payment_term', 'warehouse', 'currency', 'description',
    'comment', 'state', 'purchase_date', 'invoice_method',
    'lines', 'invoices', 'invoices_ignored', 'invoices_recreated',
    'invoice_lines', 'invoice_lines_ignored', 'moves',
    'shipment_state', 'invoice_state', 'number', 'reference',
    'shipments', 'shipment_returns', 'rec_name', 'origin',
    'untaxed_amount', 'tax_amount', 'total_amount',
    'untaxed_amount_cache', 'tax_amount_cache', 'total_amount_cache',
    'delivery_date', 'party_lang', 'contact', 'xml_id'
}

# Identify potential custom fields
potential_custom_fields = [f for f in proteus_fields if f not in standard_purchase_fields]

print(f"\n2. POTENTIAL CUSTOM FIELDS: {len(potential_custom_fields)} fields")
print("-"*80)
for field in potential_custom_fields:
    print(f"  - {field}")

# Connect to PostgreSQL to get actual table columns
print(f"\n3. COLUMNS IN POSTGRESQL TABLE 'purchase_purchase'")
print("-"*80)

try:
    conn = psycopg2.connect(
        dbname=DATABASE_NAME,
        host=DB_HOST,
        port=DB_PORT,
        user=DB_USER,
        password=DB_PASSWORD
    )
    cursor = conn.cursor()
    
    # Get all columns from purchase_purchase table
    cursor.execute("""
        SELECT 
            column_name,
            data_type,
            character_maximum_length,
            is_nullable,
            column_default
        FROM information_schema.columns 
        WHERE table_schema = 'public'
          AND table_name = 'purchase_purchase'
        ORDER BY ordinal_position;
    """)
    
    db_columns = cursor.fetchall()
    
    print(f"Total columns in database: {len(db_columns)}\n")
    
    # Standard columns that typically exist in purchase_purchase
    standard_db_columns = {
        'id', 'create_date', 'create_uid', 'write_date', 'write_uid',
        'company', 'party', 'invoice_party', 'invoice_address',
        'payment_term', 'warehouse', 'currency', 'description',
        'comment', 'state', 'purchase_date', 'invoice_method',
        'number', 'reference', 'delivery_date', 'contact',
        'shipment_state', 'invoice_state', 'origin',
        'untaxed_amount_cache', 'tax_amount_cache', 'total_amount_cache'
    }
    
    db_column_names = [col[0] for col in db_columns]
    custom_db_columns = [col for col in db_columns if col[0] not in standard_db_columns]
    
    print("Custom columns in database:")
    for col in custom_db_columns:
        col_name, data_type, max_length, nullable, default = col
        length_info = f"({max_length})" if max_length else ""
        print(f"  - {col_name:<30} {data_type}{length_info:<15} NULL: {nullable}")
    
    # Compare: Fields in Proteus vs Columns in DB
    print(f"\n4. COMPARISON: PROTEUS vs DATABASE")
    print("-"*80)
    
    # Fields in Proteus but NOT as direct columns in DB (might be related fields, functions, etc.)
    proteus_only = set(potential_custom_fields) - set(db_column_names)
    if proteus_only:
        print(f"\nFields in Proteus but NOT as columns in DB ({len(proteus_only)}):")
        print("(These might be Many2One, One2Many, Function fields, etc.)")
        for field in sorted(proteus_only):
            print(f"  - {field}")
    
    # Columns in DB but NOT visible in Proteus (these are the problem!)
    db_only = set([col[0] for col in custom_db_columns]) - set(proteus_fields)
    if db_only:
        print(f"\n⚠️  COLUMNS IN DATABASE BUT NOT VISIBLE IN PROTEUS ({len(db_only)}):")
        print("(These fields MUST be added to the Python model!)")
        for field in sorted(db_only):
            print(f"  - {field}")
    
    # Fields that exist in BOTH Proteus and DB
    both = set(potential_custom_fields) & set([col[0] for col in custom_db_columns])
    if both:
        print(f"\n✓ Custom fields properly defined in BOTH Proteus and DB ({len(both)}):")
        for field in sorted(both):
            print(f"  - {field}")
    
    cursor.close()
    conn.close()
    
except Exception as e:
    print(f"Error connecting to PostgreSQL: {e}")

# Test persistence of custom fields
print(f"\n5. TESTING FIELD PERSISTENCE")
print("-"*80)

try:
    # Find a draft purchase to test
    drafts = Purchase.find([('state', '=', 'draft')], limit=1)
    
    if drafts:
        test_purchase = drafts[0]
        test_id = test_purchase.id
        
        print(f"Testing with purchase ID: {test_id}")
        print("\nTesting custom fields (attempting to set and save):\n")
        
        # Test a sample of custom fields
        test_fields = {}
        
        # Add fields to test if they exist
        if 'reference' in potential_custom_fields:
            test_fields['reference'] = 'TEST_REF'
        if 'crop' in potential_custom_fields:
            test_fields['crop'] = 'TEST_CROP'
        if 'forex' in potential_custom_fields:
            test_fields['forex'] = 'TEST_FOREX'
        if 'broker' in potential_custom_fields:
            test_fields['broker'] = 'TEST_BROKER'
        if 'certif' in potential_custom_fields:
            test_fields['certif'] = 'TEST_CERT'
        if 'wb' in potential_custom_fields:
            test_fields['wb'] = 'TEST_WB'
        
        for field_name, test_value in test_fields.items():
            try:
                original_value = getattr(test_purchase, field_name, None)
                setattr(test_purchase, field_name, test_value)
                test_purchase.save()
                
                # Reload
                reloaded = Purchase(test_id)
                new_value = getattr(reloaded, field_name, None)
                
                if new_value == test_value:
                    print(f"  ✓ {field_name}: PERSISTS correctly")
                    # Restore original value
                    setattr(reloaded, field_name, original_value)
                    reloaded.save()
                else:
                    print(f"  ✗ {field_name}: Does NOT persist (expected: '{test_value}', got: '{new_value}')")
                    
            except Exception as e:
                print(f"  ✗ {field_name}: Error - {str(e)[:60]}")
    else:
        print("No draft purchases found for testing")
        
except Exception as e:
    print(f"Error during persistence testing: {e}")

print("\n" + "="*80)
print("SUMMARY & RECOMMENDATIONS")
print("="*80)
print("""
Next steps for your colleague:

1. Review the "⚠️ COLUMNS IN DATABASE BUT NOT VISIBLE IN PROTEUS" section
   → These fields exist in PostgreSQL but are missing from the Python model

2. Review fields that "Does NOT persist" in the testing section
   → These fields are visible but not working correctly

3. Add missing fields to your custom Tryton module:

   File: modules/your_custom_module/purchase.py
   
   from trytond.pool import PoolMeta
   from trytond.model import fields
   
   class Purchase(metaclass=PoolMeta):
       __name__ = 'purchase.purchase'
       
       # Add each missing field with appropriate type:
       custom_field = fields.Char('Custom Field')
       custom_number = fields.Integer('Custom Number')
       custom_date = fields.Date('Custom Date')
       custom_many2one = fields.Many2One('other.model', 'Reference')
       # etc...

4. Increment module version in tryton.cfg

5. Update module: trytond-admin -d tradon -u your_custom_module

6. Restart Tryton server

7. Re-run this script to verify all fields work correctly
""")