const db = require('./backend/db-sqlite'); async function fix() { const fixes = [ // return_records - all missing columns from returns.js route "ALTER TABLE return_records ADD COLUMN items TEXT DEFAULT ''", "ALTER TABLE return_records ADD COLUMN total_quantity REAL DEFAULT 0", "ALTER TABLE return_records ADD COLUMN total_amount REAL DEFAULT 0", "ALTER TABLE return_records ADD COLUMN cost_adjustment REAL DEFAULT 0", "ALTER TABLE return_records ADD COLUMN refund_amount REAL DEFAULT 0", "ALTER TABLE return_records ADD COLUMN attachments TEXT DEFAULT ''", "ALTER TABLE return_records ADD COLUMN project_id INTEGER DEFAULT 0", "ALTER TABLE return_records ADD COLUMN updated_at DATETIME DEFAULT CURRENT_TIMESTAMP", // payment_plans - make code nullable by recreating table // First add all missing columns "ALTER TABLE payment_plans ADD COLUMN code TEXT DEFAULT ''", // projects - add all missing "ALTER TABLE projects ADD COLUMN created_at DATETIME DEFAULT CURRENT_TIMESTAMP", "ALTER TABLE projects ADD COLUMN updated_at DATETIME DEFAULT CURRENT_TIMESTAMP", // project_material_inventory table (needed by returns) `CREATE TABLE IF NOT EXISTS project_material_inventory ( id INTEGER PRIMARY KEY AUTOINCREMENT, project_id INTEGER, product_id INTEGER, total_quantity REAL DEFAULT 0, current_quantity REAL DEFAULT 0, returned_quantity REAL DEFAULT 0, total_amount REAL DEFAULT 0, average_price REAL DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP )`, ]; for (const sql of fixes) { try { await db.query(sql); console.log('OK:', sql.substring(0, 70)); } catch(e) { const msg = e.message || ''; if (msg.includes('duplicate') || msg.includes('already exists')) { console.log('SKIP:', sql.substring(0, 70)); } else { console.log('ERR:', msg.substring(0, 100)); } } } // Fix payment_plans.code NOT NULL constraint - recreate table console.log('\n--- Fixing payment_plans.code NOT NULL ---'); try { const info = await db.query("PRAGMA table_info(payment_plans)"); const cols = info.rows.map(r => `${r.name} ${r.type}${r.notnull ? '' : ''}${r.dflt_value ? ' DEFAULT ' + r.dflt_value : ''}${r.pk ? ' PRIMARY KEY' + (r.pk === 1 && r.type === 'INTEGER' ? ' AUTOINCREMENT' : '') : ''}`); console.log('Columns:', info.rows.map(r => r.name).join(', ')); // Create new table with code having default const colDefs = info.rows.map(r => { let def = `${r.name} ${r.type}`; if (r.pk) def += ' PRIMARY KEY AUTOINCREMENT'; else { if (r.name === 'code') def += " DEFAULT ''"; else if (r.dflt_value) def += ` DEFAULT ${r.dflt_value}`; else if (r.notnull && r.type === 'INTEGER') def += ' DEFAULT 0'; else if (r.notnull && r.type.includes('TEXT')) def += " DEFAULT ''"; else if (r.type.includes('REAL')) def += ' DEFAULT 0'; } return def; }); await db.query(`CREATE TABLE payment_plans_new (${colDefs.join(', ')})`); const colNames = info.rows.map(r => r.name).join(', '); await db.query(`INSERT INTO payment_plans_new (${colNames}) SELECT ${colNames} FROM payment_plans`); await db.query(`DROP TABLE payment_plans`); await db.query(`ALTER TABLE payment_plans_new RENAME TO payment_plans`); console.log('OK: payment_plans table fixed - code now has default'); } catch(e) { console.log('ERR:', e.message.substring(0, 200)); } console.log('\nComprehensive fix done!'); process.exit(); } fix();