511 lines
12 KiB
JavaScript
Executable File
511 lines
12 KiB
JavaScript
Executable File
|
|
var Conf = {
|
|
appName: 'Verdnatura'
|
|
,dsName: 'verdnatura'
|
|
,dsPath: 'HKCU\\Software\\ODBC\\ODBC.INI\\verdnatura'
|
|
,regPath: 'HKCU\\Software\\Verdnatura\\vn-access'
|
|
,remoteUrl: 'https://verdnatura.es/vn-access'
|
|
,dbHost: 'db.verdnatura.es'
|
|
,defaultModule: 'tpv'
|
|
,defaultLocale: 'es'
|
|
,dbName: 'vn2008'
|
|
,maxCorruptSize: 600
|
|
};
|
|
|
|
var Locale = {
|
|
es: {
|
|
"Enter a user name":
|
|
"Introduce un nombre de usuario"
|
|
,"Enter a password":
|
|
"Introduce una contraseña"
|
|
,"Server can't be reached":
|
|
"No se ha podido conectar con el servidor"
|
|
,"Updating":
|
|
"Actualizando"
|
|
,"Bad login":
|
|
"Usuario o contraseña incorrectos"
|
|
,"Application it's already open":
|
|
"La aplicación ya está abierta"
|
|
,"Loading":
|
|
"Cargando"
|
|
,"Error while updating":
|
|
"Error al actualizar"
|
|
,"Microsoft Access 2003 is not installed":
|
|
"Microsoft Access 2003 no está instalado en el sistema"
|
|
,"MDB file not found":
|
|
"No se encontro el fichero MDB"
|
|
,"Cache files have been deleted":
|
|
"Se han borrado todos los ficheros cacheados"
|
|
}
|
|
};
|
|
|
|
var App = {
|
|
shell: new ActiveXObject('WScript.Shell'),
|
|
fso: new ActiveXObject('scripting.filesystemobject'),
|
|
|
|
init: function() {
|
|
var width = 420;
|
|
var height = 420;
|
|
|
|
window.resizeTo(width, height);
|
|
window.moveTo((screen.width - width) / 2, (screen.height - height) / 2);
|
|
},
|
|
|
|
onLoad: function() {
|
|
// Initializes the global variables
|
|
|
|
var split = Verdnatura.commandLine.match(/(?:[^\s"]+|"[^"]*")+/g);
|
|
|
|
if (split.length > 1)
|
|
this.module = split[1].replace(/^"+|"+$/g, '');
|
|
if (!this.module)
|
|
this.module = Conf.defaultModule;
|
|
|
|
this.appDir = this.getEnv('ProgramFiles') +'\\'+ Conf.appName;
|
|
this.moduleDir = this.shell.SpecialFolders('AppData') +'\\'+ Conf.appName;
|
|
this.compressFile = this.getEnv('TEMP') +'\\'+ this.module +'.7z';
|
|
this.mdbFile = this.moduleDir +'\\'+ this.module +'.mdb';
|
|
this.lockFile = this.moduleDir +'\\'+ this.module +'.ldb';
|
|
|
|
// Creates the necessary registry entries
|
|
|
|
var configured = this.regRead(Conf.regPath, 'configured');
|
|
|
|
if (!configured) {
|
|
var path;
|
|
|
|
// Creates the Access configuration entries
|
|
|
|
path = 'HKCU\\Software\\Microsoft\\Office\\11.0\\Access\\Settings';
|
|
this.regWrites(path, 'REG_DWORD', {
|
|
'Confirm Document Deletions' : 0,
|
|
'Confirm Action Queries' : 0,
|
|
'Confirm Record Changes' : 0
|
|
});
|
|
|
|
path = 'HKCU\\Software\\Microsoft\\Office\\11.0\\Access\\Security';
|
|
this.regWrite(path, 'Level', 1, 'REG_DWORD');
|
|
|
|
// Creates the MySQL ODBC connection
|
|
|
|
var driverPath = this.getEnv('ProgramFiles')
|
|
+'\\MySQL\\Connector ODBC 5.1\\myodbc5.dll';
|
|
|
|
var params = {
|
|
'Driver' : driverPath,
|
|
'DESCRIPTION' : Conf.appName,
|
|
'SERVER' : Conf.dbHost,
|
|
'DATABASE' : Conf.dbName,
|
|
'SSLCA' : this.appDir +'\\cacert.pem',
|
|
'SSLVERIFY' : 1,
|
|
'AUTO_RECONNECT' : 1
|
|
};
|
|
|
|
this.createOdbc(
|
|
Conf.dsName,
|
|
'Mysql ODBC 5.1 Driver',
|
|
params
|
|
);
|
|
|
|
// Marks the application as configured
|
|
|
|
this.regWrite(Conf.regPath, 'configured', 1, 'REG_DWORD');
|
|
}
|
|
|
|
// Loads the form data
|
|
|
|
var user = this.regRead(Conf.dsPath, 'UID');
|
|
var password = this.regRead(Conf.dsPath, 'PWD');
|
|
var remember = this.regRead(Conf.regPath, 'remember');
|
|
|
|
if (user)
|
|
this.$('user').value = user;
|
|
|
|
if (remember && password) {
|
|
this.$('password').value = password;
|
|
this.$('remember').checked = true;
|
|
this.onEnterClick();
|
|
} else
|
|
this.resetForm(true);
|
|
},
|
|
|
|
resetForm: function(clearPassword) {
|
|
if (clearPassword)
|
|
this.$('password').value = '';
|
|
|
|
this.$('user').focus();
|
|
this.$('user').select();
|
|
},
|
|
|
|
createOdbc: function(dsName, driverName, params) {
|
|
var odbcPath = 'HKCU\\Software\\ODBC\\ODBC.INI\\';
|
|
|
|
this.regWrites(odbcPath + dsName, 'REG_SZ', params);
|
|
this.regWrite(odbcPath + 'ODBC Data Sources',
|
|
dsName, driverName, 'REG_SZ');
|
|
},
|
|
|
|
disableUi: function(disabled, loadMessage) {
|
|
if (disabled)
|
|
this.hideMessage();
|
|
else
|
|
loadMessage = '';
|
|
|
|
this.$('loading-message').innerHTML = loadMessage;
|
|
|
|
this.$('user').disabled = disabled;
|
|
this.$('password').disabled = disabled;
|
|
this.$('remember').disabled = disabled;
|
|
this.$('enter').disabled = disabled;
|
|
|
|
var display = disabled ? 'block' : 'none';
|
|
this.$('background').style.display = display;
|
|
this.$('spinner').style.display = display;
|
|
},
|
|
|
|
onCleanCacheClick: function() {
|
|
setTimeout(function() { App.cleanCache(); });
|
|
},
|
|
|
|
cleanCache: function() {
|
|
if (this.fso.folderExists(this.moduleDir)) {
|
|
var folder = this.fso.getFolder(this.moduleDir);
|
|
var files = new Enumerator(folder.files);
|
|
|
|
for (; !files.atEnd(); files.moveNext()) {
|
|
var file = files.item();
|
|
if (/\.mdb$/.test(file.name) && file.name != 'config.mdb')
|
|
try {
|
|
file.Delete();
|
|
} catch (e) {}
|
|
}
|
|
}
|
|
|
|
this.showMessage(_('Cache files have been deleted'), 'notice');
|
|
},
|
|
|
|
onKeyPress: function(event) {
|
|
switch (event.keyCode) {
|
|
case 13: // Enter
|
|
this.onEnterPress(event);
|
|
break;
|
|
case 27: // Esc
|
|
window.close();
|
|
break;
|
|
}
|
|
},
|
|
|
|
onEnterPress: function(event) {
|
|
var target = event.target || event.srcElement;
|
|
|
|
if (target && target.id == 'user' && this.$('password').value == '') {
|
|
this.$('password').focus();
|
|
return;
|
|
}
|
|
|
|
this.onEnterClick();
|
|
},
|
|
|
|
onEnterClick: function() {
|
|
this.disableUi(true, _('Loading'));
|
|
setTimeout(function() { App.login(); });
|
|
},
|
|
|
|
login: function() {
|
|
try {
|
|
var user = this.$('user').value;
|
|
var password = this.$('password').value;
|
|
|
|
if (!user || user === '')
|
|
throw new Error(_('Enter a user name'));
|
|
if (!password || password === '')
|
|
throw new Error(_('Enter a password'));
|
|
|
|
this.regWrite(Conf.dsPath, 'UID', user, 'REG_SZ');
|
|
this.regWrite(Conf.dsPath, 'PWD', password, 'REG_SZ');
|
|
|
|
var version = this.fetchVersion();
|
|
|
|
if (version) {
|
|
this.disableUi(true, _('Updating'));
|
|
var remoteFile;
|
|
|
|
if (version.code == 'last') {
|
|
remoteFile = this.module +'.7z?';
|
|
remoteFile += version.number
|
|
? 'v'+ version.number
|
|
: new Date().getTime();
|
|
} else {
|
|
remoteFile = '.archive/'+ this.module +'/'+ version.number;
|
|
}
|
|
|
|
remoteFile = Conf.remoteUrl +'/'+ remoteFile;
|
|
|
|
var request = new ActiveXObject('MSXML2.XMLHTTP');
|
|
request.open('GET', remoteFile, true);
|
|
request.onreadystatechange = function() {
|
|
App.onRequestReady(request);
|
|
};
|
|
request.send();
|
|
} else
|
|
this.openMdb();
|
|
} catch (err) {
|
|
this.catchError(err);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Gets information about the version to download.
|
|
*
|
|
* @return {Object} Version information or %null if local is up-to-date
|
|
*/
|
|
fetchVersion: function() {
|
|
// Gets the last version number using the MySQL ODBC connection
|
|
|
|
var mysqlConn = new ActiveXObject('ADODB.Connection');
|
|
|
|
try {
|
|
mysqlConn.open(Conf.dsName);
|
|
} catch (err) {
|
|
var dbErrors = mysqlConn.errors;
|
|
|
|
if (dbErrors.count > 0) {
|
|
var newErr;
|
|
var dbError = dbErrors.item(0);
|
|
|
|
switch (dbError.NativeError) {
|
|
case 1045: // Access denied
|
|
clearPassword = true;
|
|
newErr = new Error(_('Bad login'));
|
|
newErr.code = 'BadLogin';
|
|
break;
|
|
case 2003: // Can't connect
|
|
newErr = new Error(_('Server can\'t be reached'));
|
|
break;
|
|
default:
|
|
errorMsg = dbError.description;
|
|
}
|
|
|
|
dbErrors.clear();
|
|
throw newErr;
|
|
} else
|
|
throw err;
|
|
}
|
|
|
|
var sql = "SELECT version FROM versiones WHERE programa = '"+ this.module +"'";
|
|
var rs = mysqlConn.execute(sql);
|
|
|
|
var lastVersion = rs.EOF ? null : parseInt(rs.fields(0).value);
|
|
var version = {
|
|
code: 'last',
|
|
number: lastVersion
|
|
};
|
|
|
|
rs.close();
|
|
mysqlConn.close();
|
|
|
|
if (this.$('previous-version').checked && lastVersion > 1)
|
|
version = {
|
|
code: 'previous',
|
|
number: lastVersion - 1
|
|
};
|
|
|
|
// Checks if it's already open
|
|
|
|
if (this.fso.fileExists(this.lockFile))
|
|
try {
|
|
this.fso.deleteFile(this.lockFile);
|
|
return version;
|
|
} catch (e) {
|
|
throw new Error(_('Application it\'s already open'));
|
|
}
|
|
|
|
// Checks if MDB exists
|
|
|
|
if (!this.fso.fileExists(this.mdbFile))
|
|
return version;
|
|
|
|
// If it's abnormaly bigger, maybe is corrupted, so force download
|
|
|
|
var file = this.fso.getFile(this.mdbFile);
|
|
|
|
if (file.size > Conf.maxCorruptSize * 1024 * 1024)
|
|
return version;
|
|
|
|
// Obtains the local version number from the MDB file
|
|
|
|
var localVersion;
|
|
|
|
try {
|
|
var mdbConn = new ActiveXObject('ADODB.Connection');
|
|
mdbConn.open('Provider=Microsoft.Jet.OLEDB.4.0; Data Source='+ this.mdbFile +';');
|
|
|
|
var oRs = new ActiveXObject('ADODB.Recordset');
|
|
oRs.Open('SELECT Version FROM tblVariables', mdbConn);
|
|
localVersion = oRs.EOF ? -1 : parseInt(oRs('Version'));
|
|
|
|
oRs.close();
|
|
mdbConn.close();
|
|
} catch (e) {}
|
|
|
|
// Compares the local version with the requested version
|
|
|
|
return !localVersion || localVersion != version.number
|
|
? version
|
|
: null;
|
|
},
|
|
|
|
onRequestReady: function(request) {
|
|
if (request.readyState !== 4)
|
|
return;
|
|
|
|
try {
|
|
if (request.status !== 200)
|
|
throw new Error('HTTP: '+ request.statusText);
|
|
|
|
if (this.fso.fileExists(this.compressFile))
|
|
this.fso.deleteFile(this.compressFile);
|
|
|
|
var stream = new ActiveXObject('ADODB.Stream');
|
|
stream.open();
|
|
stream.Type = 1; //adTypeBinary
|
|
stream.write(request.responseBody);
|
|
stream.Position = 0;
|
|
stream.saveToFile(this.compressFile, 2);
|
|
stream.close();
|
|
|
|
if (this.fso.fileExists(this.mdbFile))
|
|
this.fso.deleteFile(this.mdbFile);
|
|
|
|
this.run('7za e "'+ this.compressFile +'" -o"'+ this.moduleDir +'"', true);
|
|
this.fso.deleteFile(this.compressFile);
|
|
} catch (e) {
|
|
alert(_('Error while updating') +': '+ e.message);
|
|
}
|
|
|
|
try {
|
|
if (!this.fso.fileExists(this.mdbFile))
|
|
throw new Error(_('MDB file not found'));
|
|
|
|
this.openMdb();
|
|
} catch (e) {
|
|
this.catchError(e);
|
|
}
|
|
},
|
|
|
|
openMdb: function() {
|
|
var remember = this.$('remember').checked ? 1 : 0;
|
|
this.regWrite(Conf.regPath, 'remember', remember, 'REG_DWORD');
|
|
|
|
var programFiles = this.getEnv('ProgramFiles');
|
|
var accessBin = programFiles +'\\Microsoft Office\\OFFICE11\\MSACCESS.EXE';
|
|
|
|
if (!this.fso.fileExists(accessBin))
|
|
throw new Error(_('Microsoft Access 2003 is not installed'));
|
|
|
|
this.shell.exec('"'+ accessBin +'" "'+ this.mdbFile +'"');
|
|
window.close();
|
|
},
|
|
|
|
catchError: function(err) {
|
|
var clearPassword = err.code == 'BadLogin';
|
|
|
|
if (!this.$('remember').checked || clearPassword)
|
|
this.regWrite(Conf.dsPath, 'PWD', '', 'REG_SZ');
|
|
|
|
this.disableUi(false);
|
|
this.showMessage(err.message, 'error');
|
|
this.resetForm(clearPassword);
|
|
},
|
|
|
|
/**
|
|
* Displays a non-intrusive message.
|
|
*
|
|
* @param {String} message Message to display
|
|
* @param {String<error|notice>} className Message type
|
|
*/
|
|
showMessage: function(message, className) {
|
|
setTimeout(function() {
|
|
App.showMessageAsync(message, className);
|
|
});
|
|
},
|
|
|
|
showMessageAsync: function(message, className) {
|
|
if (this.messageTimeout)
|
|
clearTimeout(this.messageTimeout);
|
|
|
|
var messageDiv = this.$('message');
|
|
messageDiv.className = className;
|
|
messageDiv.innerHTML = message;
|
|
messageDiv.style.display = 'block';
|
|
this.messageTimeout = setTimeout(function() {
|
|
App.hideMessage();
|
|
}, 10000);
|
|
},
|
|
|
|
onBodyClick: function() {
|
|
this.hideMessage();
|
|
},
|
|
|
|
/**
|
|
* Hides the last displayed non-intrusive message.
|
|
*/
|
|
hideMessage: function() {
|
|
if (this.messageTimeout) {
|
|
this.$('message').style.display = 'none';
|
|
clearTimeout(this.messageTimeout);
|
|
this.messageTimeout = null;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Obtains a DOM element by it's identifier.
|
|
*
|
|
* @param {String} id The element id
|
|
*/
|
|
$: function(id) {
|
|
return document.getElementById(id);
|
|
},
|
|
|
|
run: function(command, wait) {
|
|
if (!wait)
|
|
wait = false;
|
|
|
|
this.shell.run(command, 0, wait);
|
|
},
|
|
|
|
getEnv: function(varName) {
|
|
return this.shell.expandEnvironmentStrings('%'+ varName +'%');
|
|
},
|
|
|
|
regRead: function(path, key) {
|
|
try {
|
|
var value = this.shell.regRead(path +'\\'+ key);
|
|
} catch (e) {
|
|
var value = null;
|
|
}
|
|
|
|
return value;
|
|
},
|
|
|
|
regWrite: function(path, key, value, type) {
|
|
this.shell.regWrite(path +'\\'+ key, value, type);
|
|
},
|
|
|
|
regWrites: function(path, type, values) {
|
|
for(var key in values)
|
|
this.regWrite(path, key, values[key], type);
|
|
},
|
|
|
|
onUnload: function() {
|
|
this.disableUi(false);
|
|
}
|
|
};
|
|
|
|
App.init();
|
|
|
|
function _(string) {
|
|
var translation = Locale[Conf.defaultLocale][string];
|
|
return translation ? translation : string;
|
|
}
|