355 lines
13 KiB
JavaScript
355 lines
13 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* NetGescon Import Runner
|
|
* Script automatico per import dati da Gescon a NetGescon via API
|
|
*
|
|
* Uso: node import-runner.js [--validate-only] [--step=admin|stabili|all]
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const axios = require('axios');
|
|
|
|
class NetGesconImporter {
|
|
constructor() {
|
|
this.config = {
|
|
apiUrl: process.env.NETGESCON_API_URL || 'http://localhost:8000/api/v1',
|
|
email: process.env.NETGESCON_EMAIL || 'admin@netgescon.local',
|
|
password: process.env.NETGESCON_PASSWORD || 'password',
|
|
timeout: 30000
|
|
};
|
|
|
|
this.token = null;
|
|
this.dataPath = path.join(__dirname, '..', '01-GESCON');
|
|
this.mappingPath = path.join(__dirname, '..', '02-MAPPING');
|
|
|
|
this.stats = {
|
|
startTime: new Date(),
|
|
amministratori: { importati: 0, errori: 0, duplicati: 0 },
|
|
stabili: { importati: 0, errori: 0, duplicati: 0 },
|
|
totaleOperazioni: 0,
|
|
erroriGlobali: []
|
|
};
|
|
}
|
|
|
|
log(message, level = 'INFO') {
|
|
const timestamp = new Date().toISOString();
|
|
console.log(`[${timestamp}] [${level}] ${message}`);
|
|
|
|
// Salva log su file
|
|
const logMessage = `${timestamp} [${level}] ${message}\n`;
|
|
fs.appendFileSync(path.join(__dirname, 'import.log'), logMessage);
|
|
}
|
|
|
|
async login() {
|
|
try {
|
|
this.log('Tentativo login API NetGescon...');
|
|
|
|
const response = await axios.post(`${this.config.apiUrl}/auth/login`, {
|
|
email: this.config.email,
|
|
password: this.config.password
|
|
}, {
|
|
timeout: this.config.timeout,
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json'
|
|
}
|
|
});
|
|
|
|
if (response.data.success) {
|
|
this.token = response.data.data.token;
|
|
this.log('Login API completato con successo');
|
|
return true;
|
|
} else {
|
|
throw new Error(response.data.message || 'Login fallito');
|
|
}
|
|
} catch (error) {
|
|
this.log(`Errore login API: ${error.message}`, 'ERROR');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
loadData(filename) {
|
|
try {
|
|
const filePath = path.join(this.dataPath, filename);
|
|
const rawData = fs.readFileSync(filePath, 'utf8');
|
|
return JSON.parse(rawData);
|
|
} catch (error) {
|
|
this.log(`Errore caricamento file ${filename}: ${error.message}`, 'ERROR');
|
|
return null;
|
|
}
|
|
}
|
|
|
|
loadMapping() {
|
|
try {
|
|
const mappingFile = path.join(this.mappingPath, 'campo-mapping.json');
|
|
const rawData = fs.readFileSync(mappingFile, 'utf8');
|
|
return JSON.parse(rawData);
|
|
} catch (error) {
|
|
this.log(`Errore caricamento mapping: ${error.message}`, 'ERROR');
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async importAmministratori(validateOnly = false) {
|
|
this.log('=== INIZIO IMPORT AMMINISTRATORI ===');
|
|
|
|
const data = this.loadData('amministratori.json');
|
|
if (!data) return false;
|
|
|
|
const mapping = this.loadMapping();
|
|
if (!mapping) return false;
|
|
|
|
try {
|
|
// Prepara dati per API
|
|
const apiData = {
|
|
bulk_import: true,
|
|
validate_only: validateOnly,
|
|
amministratori: data.amministratori.map(admin => this.transformAmministratore(admin, mapping))
|
|
};
|
|
|
|
this.log(`Preparati ${apiData.amministratori.length} amministratori per import`);
|
|
|
|
const response = await axios.post(`${this.config.apiUrl}/import/amministratori`, apiData, {
|
|
timeout: this.config.timeout * 2,
|
|
headers: {
|
|
'Authorization': `Bearer ${this.token}`,
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json'
|
|
}
|
|
});
|
|
|
|
if (response.data.success) {
|
|
const result = response.data.data;
|
|
this.stats.amministratori.importati = result.importati || 0;
|
|
this.stats.amministratori.errori = result.errori || 0;
|
|
this.stats.amministratori.duplicati = result.duplicati || 0;
|
|
|
|
this.log(`Import amministratori completato: ${result.importati} importati, ${result.errori} errori, ${result.duplicati} duplicati`);
|
|
|
|
if (result.dettagli) {
|
|
result.dettagli.forEach(dettaglio => {
|
|
this.log(` - ${dettaglio.codice}: ${dettaglio.status} - ${dettaglio.message || ''}`);
|
|
});
|
|
}
|
|
|
|
return true;
|
|
} else {
|
|
throw new Error(response.data.message || 'Import amministratori fallito');
|
|
}
|
|
|
|
} catch (error) {
|
|
this.log(`Errore import amministratori: ${error.message}`, 'ERROR');
|
|
if (error.response?.data?.errors) {
|
|
this.log(`Dettagli errore: ${JSON.stringify(error.response.data.errors)}`, 'ERROR');
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
transformAmministratore(admin, mapping) {
|
|
const adminMapping = mapping.amministratori;
|
|
|
|
return {
|
|
codice_amministratore: admin.codice_amministratore_new,
|
|
denominazione: admin.dati_anagrafici.denominazione,
|
|
ragione_sociale: admin.dati_anagrafici.ragione_sociale,
|
|
codice_fiscale: admin.dati_anagrafici.codice_fiscale,
|
|
partita_iva: admin.dati_anagrafici.partita_iva,
|
|
indirizzo: admin.indirizzo.via,
|
|
cap: admin.indirizzo.cap,
|
|
citta: admin.indirizzo.citta,
|
|
provincia: admin.indirizzo.provincia,
|
|
telefono: admin.contatti.telefono,
|
|
email: admin.contatti.email,
|
|
pec: admin.contatti.pec,
|
|
responsabile_nome: admin.responsabile.nome,
|
|
responsabile_cognome: admin.responsabile.cognome,
|
|
responsabile_cf: admin.responsabile.codice_fiscale,
|
|
data_nascita: admin.responsabile.data_nascita,
|
|
comune_nascita: admin.responsabile.luogo_nascita,
|
|
provincia_nascita: admin.responsabile.provincia_nascita,
|
|
sesso: admin.responsabile.sesso,
|
|
data_iscrizione_albo: admin.professionale.data_iscrizione_albo,
|
|
numero_albo: admin.professionale.numero_albo,
|
|
note: admin.sistema.note,
|
|
attivo: admin.sistema.attivo
|
|
};
|
|
}
|
|
|
|
async importStabili(validateOnly = false) {
|
|
this.log('=== INIZIO IMPORT STABILI ===');
|
|
|
|
const data = this.loadData('stabili.json');
|
|
if (!data) return false;
|
|
|
|
const mapping = this.loadMapping();
|
|
if (!mapping) return false;
|
|
|
|
try {
|
|
// Prepara dati per API
|
|
const apiData = {
|
|
bulk_import: true,
|
|
validate_only: validateOnly,
|
|
stabili: data.stabili.map(stabile => this.transformStabile(stabile, mapping))
|
|
};
|
|
|
|
this.log(`Preparati ${apiData.stabili.length} stabili per import`);
|
|
|
|
const response = await axios.post(`${this.config.apiUrl}/import/stabili`, apiData, {
|
|
timeout: this.config.timeout * 3,
|
|
headers: {
|
|
'Authorization': `Bearer ${this.token}`,
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json'
|
|
}
|
|
});
|
|
|
|
if (response.data.success) {
|
|
const result = response.data.data;
|
|
this.stats.stabili.importati = result.importati || 0;
|
|
this.stats.stabili.errori = result.errori || 0;
|
|
this.stats.stabili.duplicati = result.duplicati || 0;
|
|
|
|
this.log(`Import stabili completato: ${result.importati} importati, ${result.errori} errori, ${result.duplicati} duplicati`);
|
|
|
|
if (result.dettagli) {
|
|
result.dettagli.forEach(dettaglio => {
|
|
this.log(` - ${dettaglio.codice}: ${dettaglio.status} - ${dettaglio.message || ''}`);
|
|
});
|
|
}
|
|
|
|
return true;
|
|
} else {
|
|
throw new Error(response.data.message || 'Import stabili fallito');
|
|
}
|
|
|
|
} catch (error) {
|
|
this.log(`Errore import stabili: ${error.message}`, 'ERROR');
|
|
if (error.response?.data?.errors) {
|
|
this.log(`Dettagli errore: ${JSON.stringify(error.response.data.errors)}`, 'ERROR');
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
transformStabile(stabile, mapping) {
|
|
return {
|
|
cod_stabile_old: stabile.cod_stabile_old,
|
|
denominazione: stabile.dati_anagrafici.denominazione,
|
|
indirizzo: stabile.dati_anagrafici.indirizzo_completo,
|
|
cap: stabile.dati_anagrafici.cap,
|
|
citta: stabile.dati_anagrafici.citta,
|
|
provincia: stabile.dati_anagrafici.provincia,
|
|
codice_fiscale: stabile.dati_anagrafici.codice_fiscale,
|
|
num_condomini: stabile.struttura.num_condomini,
|
|
num_scale: stabile.struttura.num_scale,
|
|
cf_amministratore: stabile.amministrazione.cf_amministratore,
|
|
iban_bancario: stabile.dati_bancari.iban_principale,
|
|
iban_postale: stabile.dati_bancari.iban_postale,
|
|
banca: stabile.dati_bancari.banca,
|
|
abi: stabile.dati_bancari.abi,
|
|
cab: stabile.dati_bancari.cab,
|
|
intestazione: stabile.dati_bancari.intestazione,
|
|
autorizzazione: stabile.autorizzazioni?.numero,
|
|
data_nomina: stabile.amministrazione.data_nomina,
|
|
note: stabile.sistema.note,
|
|
email_amministratore: stabile.contatti?.email_amministratore,
|
|
pec_amministratore: stabile.contatti?.pec_amministratore,
|
|
pec_condominio: stabile.contatti?.pec_condominio,
|
|
migrazione_data: stabile.sistema.migrazione_data,
|
|
attivo: stabile.sistema.attivo
|
|
};
|
|
}
|
|
|
|
async generateReport() {
|
|
const endTime = new Date();
|
|
const duration = Math.round((endTime - this.stats.startTime) / 1000);
|
|
|
|
const report = {
|
|
timestamp: endTime.toISOString(),
|
|
durata_secondi: duration,
|
|
statistiche: this.stats,
|
|
successo: this.stats.erroriGlobali.length === 0
|
|
};
|
|
|
|
// Salva report su file
|
|
const reportPath = path.join(__dirname, `import-report-${endTime.getTime()}.json`);
|
|
fs.writeFileSync(reportPath, JSON.stringify(report, null, 2));
|
|
|
|
this.log('=== REPORT FINALE ===');
|
|
this.log(`Durata import: ${duration} secondi`);
|
|
this.log(`Amministratori - Importati: ${this.stats.amministratori.importati}, Errori: ${this.stats.amministratori.errori}`);
|
|
this.log(`Stabili - Importati: ${this.stats.stabili.importati}, Errori: ${this.stats.stabili.errori}`);
|
|
this.log(`Report salvato in: ${reportPath}`);
|
|
|
|
return report;
|
|
}
|
|
|
|
async run(options = {}) {
|
|
const { validateOnly = false, step = 'all' } = options;
|
|
|
|
this.log('=== AVVIO NETGESCON IMPORT RUNNER ===');
|
|
this.log(`Modalità: ${validateOnly ? 'VALIDAZIONE' : 'IMPORT COMPLETO'}`);
|
|
this.log(`Step: ${step}`);
|
|
|
|
// Login API
|
|
if (!await this.login()) {
|
|
this.log('Impossibile procedere senza login API', 'ERROR');
|
|
return false;
|
|
}
|
|
|
|
let success = true;
|
|
|
|
// Import amministratori
|
|
if (step === 'all' || step === 'admin') {
|
|
success = await this.importAmministratori(validateOnly) && success;
|
|
}
|
|
|
|
// Import stabili (solo se amministratori ok)
|
|
if ((step === 'all' || step === 'stabili') && success) {
|
|
success = await this.importStabili(validateOnly) && success;
|
|
}
|
|
|
|
// Genera report finale
|
|
await this.generateReport();
|
|
|
|
this.log(`=== IMPORT ${success ? 'COMPLETATO' : 'FALLITO'} ===`);
|
|
return success;
|
|
}
|
|
}
|
|
|
|
// Gestione parametri command line
|
|
function parseArgs() {
|
|
const args = process.argv.slice(2);
|
|
const options = {};
|
|
|
|
args.forEach(arg => {
|
|
if (arg === '--validate-only') {
|
|
options.validateOnly = true;
|
|
} else if (arg.startsWith('--step=')) {
|
|
options.step = arg.split('=')[1];
|
|
}
|
|
});
|
|
|
|
return options;
|
|
}
|
|
|
|
// Esecuzione principale
|
|
if (require.main === module) {
|
|
const options = parseArgs();
|
|
const importer = new NetGesconImporter();
|
|
|
|
importer.run(options)
|
|
.then(success => {
|
|
process.exit(success ? 0 : 1);
|
|
})
|
|
.catch(error => {
|
|
console.error('Errore fatale:', error);
|
|
process.exit(1);
|
|
});
|
|
}
|
|
|
|
module.exports = NetGesconImporter;
|