PDA

View Full Version : I cannot extend two custom controllers from one base defined controller.



maneljn
19 Feb 2015, 8:11 AM
Extjs 4.1.1

I cannot extend two custom controllers from one base defined controller. I copy the source code of my example.

The base controller is "isoacademia.controller.rexxxxxx.mant"

When i add these 2 extended controllers to my app,

"isoacademia.controller.re040102.mant"
"isoacademia.controller.re040103.mant"

the problem is that is seems to have extended from a singleton implementation, because the value of this "subconfig" property, have to be different, but they are equal.

isoacademia.controller.re040102.mant.subconfig

isoacademia.controller.re040103.mant.subconfig

Is is possible to extend customized controllers from a base controller ???



//@charset UTF-8

// Controller para extender al crear los controllers de cada tipo de documento registro iso , p.ex. re040102.mant
Ext.define('isoacademia.controller.rexxxxxx.mant', {
extend: 'Ext.app.Controller',

models:[
'tipoRegiso',
'rexxxxxx'
// El resto, se definen en cada controller extendido
],
stores:[
'tiposRegiso'
// El resto, se definen en cada controller extendido
],
views: [
'rexxxxxx.edicionCamposComunesCab',
'rexxxxxx.edicionCamposInfoRegistro'
// El resto, se definen en cada controller extendido
],

init: function() {
var me = this;

// Se definen en cada controller extendido
// Ejemplo
// me.control({
// 'isoacademia_view_re010402_mantEdicion' : {
// afterrender: me.onRenderFichaEdicion,
// guardar: me.onGuardarAction,
// cancelar: me.onCancelarAction
// }
// });
},

refs: [
],

// Definir los nombres, configuraciones y otros valores del sub-controller
// Se definen en cada controller extendido
// Ejemplo:
// // Definir los nombres, configuraciones y otros valores del sub-controller
// me.subconfig = Ext.apply(me.subconfig || {}, {
// nombreMinus: 're040102',
// nombreMinusPlural: 're040102',
// nombreMayus: 'Re040102',
// nombreMayusPlural: 'Re040102',
//
// nombreExtDirect: 'isoacademia_re040102',
// directMetodoClonarPhpNombre: 'clonarRe040102',
//
// modelNombre: 're040102',
// modelPrefijoCampos: 're040102_',
// storeNombre: 're040102',
//
// viewMantEdicion: 're040102.mantEdicion',
// viewMantEdicionAlias: 're040102_mantEdicion',
// formularioObjNombre: 'formularioRe040102',
//
// // Nombre del campo que se muestra al pedir confirmación para borrar
// confBorrarMostrarCampo: 'regiso_id',
//
// // validaciones para el pre-guardar
// preGuardar: {
// arrayCamposEscogeNombre: ['escoge_cto_nombre_fiscal'],
// arrayVentanasEscoge: ['windowEscogeContacto'],
// arrayViewMantSubfichas: ['re040102Lin_mantEdicion']
// },
//
// // Procesos que se ejecutan conscutivamente después de guardar (save) la ficha principal
// procesosMultiGuardar: [{
// nombre: 're040102Lin',
// tipo: 'subfichasSync',
// descripcionMinus: gt.dgettext('isoacademia','línea'),
// descripcionMinusPlural: gt.dgettext('isoacademia','líneas'),
// descripcionMayus: gt.dgettext('isoacademia','Línea'),
// descripcionMayusPlural: gt.dgettext('isoacademia','Líneas'),
// viewGridNombre: 're040102Lin.mantGrid',
// viewGridAlias: 're040102Lin_mantGrid',
// modelNombre: 're040102lin',
// modelPrefijoCampos: 're040102lin_',
// modelCampoEnlace: 're040102lin_recab_id'
// }],
//
// // Procesos que se ejecutan conscutivamente después de guardar correctamente todos los datos del multiguardar
// // También se lanza al clicar cancelar.
// procesosPostEditar: [{
// nombre: 'refrescarTotales',
// tipo: 'personalizado',
// metodo: me.refrescarTotalesRegistro,
// directMetodoPhpNombre: 'getRe040102TotalesPorId',
// arrayCamposRefrescar: null, // un array con los nombres de los campos con prefijo incluido, null = todos los recibidos
// arrayCamposNoRefrescar: null // un array con los nombres de los campos con prefijo incluido
// }]
//
// }, me.subconfig);

subconfig: {
procesosMultiGuardar: [],
procesosPostEditar: []
},

procesosMultiGuardar: [],
procesosPostEditar: [],

//
// Se ejecuta cuando se produce el render de la ficha de edicion
// Es decir justo cuando se ha acabado de cargar y dibujar el control (render)
// Inicializamos valores de campos, mostrar/ocultar campos dinamicamente, etc...
//
onRenderFichaEdicion: function( panelEdicion, eOpts) {
var me = this;

// Procesos que se realizan cuando se acaba de crear/dibujar el control de edicion de la ficha de mantenimiento
if (panelEdicion[me.subconfig.formularioObjNombre]) {
// Mostrar o ocultar campos dinamicos del formulario
me.camposDinamicos( panelEdicion, panelEdicion[me.subconfig.formularioObjNombre] );
}

},

//
// Nuevo registro
//
onNuevoAction: function(action, grid, event, eOpts) {
var me = this;

var store = grid.getStore();
var registroRegiso = Ext.create(isoacademiaApp.getModel('registroIso'));
var registro = Ext.create(isoacademiaApp.getModel(me.subconfig.modelNombre));
if (registroRegiso && registro) {
me.editarRegistro('nuevo', registroRegiso, registro, grid);
} else {
Ext.Msg.show({
title: gt.dgettext('isoacademia','Nuevo'),
msg: gt.dgettext('isoacademia','No se puede crear un nuevo registro iso.'),
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
}
},

//
// Editar registro
//
onEditarAction: function(action, grid, event, eOpts) {
var me = this;
var registroRegiso = grid.getSelectionModel().getSelection()[0];
if (registroRegiso) {
me.refrescarEditarRegistro('editar', registroRegiso, grid);
} else {
Ext.Msg.show({
title: gt.dgettext('isoacademia','Editar'),
msg: gt.dgettext('isoacademia','Debe seleccionar un registro iso para editar.'),
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
}
},

//
// Borrar registro
//
onBorrarAction: function(action, grid, event, eOpts) {
var me = this;
var registroRegiso = grid.getSelectionModel().getSelection()[0];
if (registroRegiso) {
me.borrarRegistro(registroRegiso, grid);
} else {
Ext.Msg.show({
title: gt.dgettext('isoacademia','Borrar'),
msg: gt.dgettext('isoacademia','Debe seleccionar un registro iso para borrar.'),
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
}
},

//
// Clonar el registro
//
onClonarAction: function(action, grid, event, eOpts) {
var me = this;
var registroRegiso = grid.getSelectionModel().getSelection()[0];
var mainStatusBar = grid.up('isoacademia_view_main').down('isoacademia_view_mainStatusBar[name="mainStatusBar"]');

if ( !me.subconfig.directMetodoClonarPhpNombre ) {
return false;
}

if ( !window["Ext"]["isoacademiaDirect"][me.subconfig.nombreExtDirect][me.subconfig.directMetodoClonarPhpNombre]) {
Ext.Msg.show({
title: gt.dgettext('isoacademia','Clonar'),
msg: gt.dgettext('isoacademia','Método clonar no definido para este tipo de registro ISO.'),
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
return false;
}

if (registroRegiso) {

// Mostrar mensaje en barra de estado
if (mainStatusBar) {
mainStatusBar.setStatus({
text: gt.dgettext('isoacademia','Clonando registro iso ...'),
iconCls: 'x-status-busy',
clear: false
});
}
// Mostrar mascara
grid.getEl().mask(gt.dgettext('isoacademia','Clonando registro iso ...'));

// Ejecutar accion a traves del proxy direct para clonar / duplicar el RE-XX-XX-XX
//Ext.isoacademiaDirect.isoacademia_re040102.clonarRe040102({
window["Ext"]["isoacademiaDirect"][me.subconfig.nombreExtDirect][me.subconfig.directMetodoClonarPhpNombre]({
regiso_id: registroRegiso.get('regiso_id'),
regiso_guid: registroRegiso.get('regiso_guid'),
regiso_empresa_id: registroRegiso.get('regiso_empresa_id'),
// pasamos fecha para control concurrencia
regiso_fechamod: Ext.Date.format(registroRegiso.get('regiso_fechamod'),'Y-m-d H:i:s')

}, function(provider, response) {

// Limpiar mask pantalla
grid.getEl().unmask();

// Cuando llega la respuesta asincrona, entonces refrescamos el registro original y añadimos el nuevo clonado
if (response.result.success) {
// Comprobar que nos llega el mismo id que hemos pedido
if (response.result.data[0]) {

// Limpiar barra de estado
if (mainStatusBar) {
mainStatusBar.clearStatus({ useDefaults:true, anim: false });
}

if (response.result.data[0].regiso_id==registroRegiso.get('regiso_id')) {
// Pasar todos los datos recibidos al registro original que estaba en el store
registroRegiso.set( response.result.data[0] );
registroRegiso.commit();

// Refrescar el grid para que muestre valores actualizados del registro
grid.getView().refresh();
// Dejamos seleccionado en la lista el registro que acabamos de guardar
grid.getSelectionModel().deselectAll( false );
if ( grid.getStore().findRecord('regiso_id',registroRegiso.get('regiso_id'),0,false,false,true) ) {
grid.getSelectionModel().select([registroRegiso], false, false);
}
}

// Comprobar que nos llega un nuevo id con el registro nuevo clonado
if (response.result.data[1]) {
// Crear registro para guardar los datos "clonados" recibidos (model)
var registroClonado = Ext.create(isoacademiaApp.getModel('registroIso'));
// Pasar todos los datos recibidos al registro que estaba en el store
registroClonado.set( response.result.data[1] );
registroClonado.commit();
// Insertar en la parte superior del grid.
grid.getStore().insert(0,registroClonado);

// Refrescar el grid
grid.getView().refresh();

// Dejamos seleccionado en la lista el registro que nuevo que acabamos de clonar
grid.getSelectionModel().deselectAll( false );
if ( grid.getStore().findRecord('regiso_id',registroClonado.get('regiso_id'),0,false,false,true) ) {
grid.getSelectionModel().select([registroClonado], false, false);
}

// Mostrar mensaje correcto
Ext.Msg.show({
title: gt.dgettext('isoacademia','Clonar registro iso'),
msg: gt.dgettext('isoacademia','Guardado correctamente.'),
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.INFO
});

return true;
}
}
}

// Mostrar mensaje error
if (mainStatusBar) {
mainStatusBar.setStatus({
text: (response.result.message ? response.result.message : gt.dgettext('isoacademia','No se ha podido clonar el registro iso.')),
iconCls: 'x-status-error',
clear: {anim: false, useDefaults: true }
});
}

// Mostrar mensaje que no se puede clonar
Ext.Msg.show({
title: gt.dgettext('isoacademia','Clonar registro iso'),
msg: (response.result.message ? response.result.message : gt.dgettext('isoacademia','No se ha podido clonar el registro iso.<br />Vuelva a refrescar la lista.')),
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.WARNING,
fn: function(btn, text, opt) {
// nada
}
});

return false;
});

} else {
Ext.Msg.show({
title: gt.dgettext('isoacademia','Clonar'),
msg: gt.dgettext('isoacademia','Debe seleccionar un registro iso para clonar.'),
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
}
},

//
// Refrescar un registro ya existente y después Editar el registro
// Ojo se recibe el registro del documento y se refresca obligatoriamente el registro del RE040102 one-to-one
//
refrescarEditarRegistro: function( modo, registroRegiso, grid ) {
var me = this;

if (registroRegiso) {
if (grid) {

// Obligatorio refrescar SIEMPRE !!
// Si lo tenemos configurado en esinube para no hacer los refrescos previos vamos directament a editar.
//if (!esinubeConfig.cfg_av_refrescarRegEditar) {
// // Ahora ya podemos editar el registro
// me.editarRegistro( modo, registroRegiso, registro, grid );
// return true;
//}

// Mostrar "cargando" en barra de estado
var mainStatusBar = grid.up('isoacademia_view_main').down('isoacademia_view_mainStatusBar[name="mainStatusBar"]');
if (mainStatusBar) {
mainStatusBar.setStatus({
text: gt.dgettext('isoacademia','Cargando registro para editar ... ') + registroRegiso.get('regiso_id'),
iconCls: 'x-status-busy',
clear: false
});
}

// Ejecutar funcion extdirect para refrescar el registro que corresponde al id solicitado para editar
// Asi cogemos los datos mas recientes para editar
//Ext.isoacademiaDirect.isoacademia_re040102.getRe040102({
window["Ext"]["isoacademiaDirect"][me.subconfig.nombreExtDirect]["get" + me.subconfig.nombreMayusPlural]({
filter: [{
property: me.subconfig.modelPrefijoCampos + 'regiso_id',
value: registroRegiso.get('regiso_id')
}]

}, function(provider, response) {

// Cuando llega la respuesta asincrona, entonces editamos el registro si ha ido bien la carga del refresco
if (response.result.success) {
// Comprobar que nos llega el mismo id que hemos pedido
if (response.result.data[0]) {

// Limpiar barra de estado
if (mainStatusBar) {
mainStatusBar.clearStatus({ useDefaults:true, anim: false });
}

if (response.result.data[0][me.subconfig.modelPrefijoCampos + 'regiso_id'] == registroRegiso.get('regiso_id')) {
// Pasar los datos recibidos al registro del documento que estaba en el store
// Asignará solo los campos que estan en el modelo del documento regiso_xxxxx
registroRegiso.set( response.result.data[0] );
registroRegiso.commit();

// Ahora creamos un registro del modelo RExxxxxx concreto (p.ex. model.re040102)
// para poder editar y le cargamos los datos recibidos
var registro = Ext.create(isoacademiaApp.getModel(me.subconfig.modelNombre));
registro.set( response.result.data[0] );
registro.commit();

// Ahora ya podemos editar el registro
me.editarRegistro( modo, registroRegiso, registro, grid );
return true;
}
}
}

// Mostrar mensaje error
if (mainStatusBar) {
mainStatusBar.setStatus({
text: gt.dgettext('isoacademia','No se ha podido cargar/refrescar el registro antes de editar.'),
iconCls: 'x-status-error',
clear: {anim: false, useDefaults: true }
});
}

// Mostrar mensaje que no se puede editar el registro
Ext.Msg.show({
title: gt.dgettext('isoacademia','Editar'),
msg: gt.dgettext('isoacademia','No se ha podido cargar/refrescar el registro antes de editar.<br />Inténtelo dentro de unos segundos o vuelva a refrescar la lista.'),
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.WARNING,
fn: function(btn, text, opt) {
// nada
}
})
return false;
}
);
}
}
},

//
// Editar un registro
//
editarRegistro: function( modo, registroRegiso, registro, grid ) {
var me = this;

if (registroRegiso && registro) {
if (grid) {
var tabpanel = grid.up('isoacademia_view_registrosIso_mant'); // Se usa el grid i mant de DOCUMENTOS
if (tabpanel) {
// Crear la vista de edicion (formulario de edicion)
//var mantEdicion = isoacademiaApp.getView('re040102.mantEdicion');
var mantEdicion = isoacademiaApp.getView(me.subconfig.viewMantEdicion);
if (mantEdicion) {
// Comprobar si ya está abierta esta ficha por su idAsociado y simplemente mostrar
//var fichasAbiertas = tabpanel.query('isoacademia_view_re040102_mantEdicion[name="edicionRe040102_id_'+registro.get('re040102_id').toString()+'"]');
var fichasAbiertas = tabpanel.query('isoacademia_view_' + me.subconfig.viewMantEdicionAlias + '[name="edicion' + me.subconfig.nombreMayus +'_id_'+registro.get(me.subconfig.modelPrefijoCampos + 'id').toString()+'"]');
if (modo!='nuevo' && fichasAbiertas.length > 0) {
// Mostrar la ficha ya abierta anteriormente
tabpanel.setActiveTab(fichasAbiertas[0]);
} else {
// Crear la vista de la ficha para editar
var mantEdicionView = mantEdicion.create({
name: 'edicion' + me.subconfig.nombreMayus +'_id_' + registro.get(me.subconfig.modelPrefijoCampos + 'id').toString(),
modo: modo,
registroRegisoAsociado: registroRegiso,
registroAsociado: registro,
gridAsociado: grid
});
// Abrir opcion en un nuevo tab
tabpanel.add( mantEdicionView );
tabpanel.setActiveTab( mantEdicionView );
}
}
}
}
}
},

//
// Borrar un registro
// No usamos el método destroy del data.model porque tenemos que enviar un model del rexxxxxx, y el que tenemos en el
// grid es del tipo registroIso. Lo hacemos llamando al extdirect con el metodo destroy directamente, como en el
// proceso de clonar.
//
borrarRegistro: function( registroRegiso, grid ) {
var me = this;

if (registroRegiso) {

if ( !window["Ext"]["isoacademiaDirect"][me.subconfig.nombreExtDirect]["destroy" + me.subconfig.nombreMayus]) {
Ext.Msg.show({
title: gt.dgettext('isoacademia','Borrar'),
msg: gt.dgettext('isoacademia','Método destroy no definido para este tipo de registro ISO.'),
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
return false;
}

mensajeConf = gt.dgettext('isoacademia','Seguro que desea borrar el registro iso ?') + '<br />' + (me.subconfig.confBorrarMostrarCampo ? registroRegiso.get(me.subconfig.confBorrarMostrarCampo) : ''),

// Pedir conformidad para borrar
Ext.Msg.show({
title: gt.dgettext('isoacademia','Borrar'),
msg: mensajeConf,
buttons: Ext.Msg.YESNO,
//icon: Ext.MessageBox.QUESTION,
icon: Ext.MessageBox.WARNING,
fn: function(btn, text, opt) {
if (btn == 'yes') {

// Mostrar "borrando" en barra de estado
var mainStatusBar = grid.up('isoacademia_view_main').down('isoacademia_view_mainStatusBar[name="mainStatusBar"]');
if (mainStatusBar) {
mainStatusBar.setStatus({
text: gt.dgettext('isoacademia','Borrando registro ...') + ' ' + (me.subconfig.confBorrarMostrarCampo ? registroRegiso.get(me.subconfig.confBorrarMostrarCampo) : ''),
iconCls: 'x-status-busy',
clear: false
});
}
// Mostrar mascara
grid.getEl().mask(gt.dgettext('isoacademia','Borrando registro ...'));


// Ejecutar accion a traves del proxy direct para BORRAR el RE-XX-XX-XX
//Ext.isoacademiaDirect.isoacademia_re040102.destroyRe040102({
window["Ext"]["isoacademiaDirect"][me.subconfig.nombreExtDirect]["destroy" + me.subconfig.nombreMayus]({
regiso_id: registroRegiso.get('regiso_id'),
regiso_guid: registroRegiso.get('regiso_guid'),
regiso_empresa_id: registroRegiso.get('regiso_empresa_id'),
// pasamos fecha para control concurrencia
regiso_fechamod: Ext.Date.format(registroRegiso.get('regiso_fechamod'),'Y-m-d H:i:s')

}, function(provider, response) {

// Limpiar mask pantalla
grid.getEl().unmask();

// Cuando llega la respuesta asincrona, entonces refrescamos el registro original y añadimos el nuevo clonado
if (response.result.success) {

// Limpiar barra de estado
if (mainStatusBar) {
mainStatusBar.clearStatus({ useDefaults:true, anim: false });
}

// Borrar correcto. Quitar el registro Iso del store
grid.getStore().remove( registroRegiso );
// Forzar cambios hechos en el store para que no lanze operaciones con el registro borrado
grid.getStore().commitChanges();

return true;
}

// Mostrar mensaje error
if (mainStatusBar) {
mainStatusBar.setStatus({
text: (response.result.message ? response.result.message : gt.dgettext('isoacademia','No se ha podido borrar el registro iso.')),
iconCls: 'x-status-error',
clear: {anim: false, useDefaults: true }
});
}

// Mostrar mensaje que no se puede borrar
Ext.Msg.show({
title: gt.dgettext('isoacademia','Borrar registro iso'),
msg: (response.result.message ? response.result.message : gt.dgettext('isoacademia','No se ha podido borrar el registro iso.')),
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.WARNING,
fn: function(btn, text, opt) {
// nada
}
});

return false;
});
}
}
})
}
},

//
// Cancelar y volver
//
onCancelarAction: function(action, panelEdicion, event, eOpts) {
var me = this;
//var formulario = panelEdicion.formularioRe040102;
var formulario = panelEdicion[me.subconfig.formularioObjNombre];
var registroRegiso = panelEdicion.registroRegisoAsociado;
var registro = formulario.getRecord()
var grid = panelEdicion.up('isoacademia_view_registrosIso_mant').down('isoacademia_view_registrosIso_mantGrid[name="gridRegistrosIso"]');

if (panelEdicion.modo=="nuevo") {
// Eliminar registro creado porque aun no se ha agregado al store
registroRegiso = null;
registro = null;
} else if (panelEdicion.modo=="editar") {
// Volver a poner los campos modificados tal como estaban al principio
registroRegiso.set( registroRegiso.modified );
// Forzar cambios hechos en el store para que no lanze operaciones con el registro tocado
panelEdicion.storeAsociado.commitChanges();
}
if (panelEdicion.modo=='nuevo') {
// Cerrar el panel de edicion de este registro
Ext.destroy(panelEdicion);
} else {
// Lanzar los procesos posteditar (refrescar totales, etc...) pero sin pasar por "multiguardar"
me.postEditar(registroRegiso, registro, panelEdicion);
// El postEditar es la última parte de la edición y ya hace el destroy del panelEdicion
if (panelEdicion.modo=="editar") {
registro = null;
}
}
},

//
// Guardar registro
//
onGuardarAction: function(action, panelEdicion, event, eOpts) {
var me = this;
//var formulario = panelEdicion.formularioRe040102;
var formulario = panelEdicion[me.subconfig.formularioObjNombre];
var formBasic = formulario.getForm();
var registroRegiso = panelEdicion.registroRegisoAsociado;
var registro = formulario.getRecord();
var mainStatusBar = panelEdicion.up('isoacademia_view_main').down('isoacademia_view_mainStatusBar[name="mainStatusBar"]');
var grid = panelEdicion.up('isoacademia_view_registrosIso_mant').down('isoacademia_view_registrosIso_mantGrid[name="gridRegistrosIso"]');

if (formulario && panelEdicion.storeAsociado) {

// Validar campos escoge, windows escoge, campos formulario principal, formularios anidados, etc...
// antes de proceder a guardar
if (!me.validarPreGuardar( panelEdicion, grid, formulario, registroRegiso, registro )) {
return false;
}

// Cargar valores del formulario en el registro asociado
registro.set( formulario.getValues() );

// asignar el proxy direct del store que corresponde al registro
//registro.setProxy(panelEdicion.storeAsociado.getProxy());
registro.setProxy(isoacademiaApp.getStore(me.subconfig.storeNombre).getProxy());

// Mostrar "guardando" en barra de estado
if (mainStatusBar) {
mainStatusBar.setStatus({
text: gt.dgettext('isoacademia','Guardando registro ... ') + registro.get(me.subconfig.modelPrefijoCampos + 'id'),
iconCls: 'x-status-busy',
clear: false
});
}
// Mostrar mascara
panelEdicion.getEl().mask(gt.dgettext('isoacademia','Guardando...'));

// Iniciar tabla de configuraciones del proceso multiguardar
// Asi se pueden ejecutar los procesos de guardar asincronos de forma consecutiva si van bien
// y al final cerrar el formulario de edicion o dejarlo si hay errores en cualquier guardar.
me.procesosMultiGuardar = me.subconfig.procesosMultiGuardar;

// Guardar registro a traves del proxy direct
registro.save({
// Procesar respuesta
callback: function( records, operation) {
panelEdicion.getEl().unmask();

if (operation.wasSuccessful()) {
// Limpiar barra de estado
if (mainStatusBar) {
mainStatusBar.clearStatus({ useDefaults:true, anim: false });
}
//console.log(operation.response);
//console.log(operation.response.result);
// Guardar correcto
if ( panelEdicion.modo=="nuevo" ) {
// OJO el storeAsociado es el de la tabla RegistrosIso
// Asignamos los valores recibidos despues de guardar al registro del registro-iso
// solo se actualizaran los campos regiso_xxxx
registroRegiso.set( registro.getData() );
// Agregar el registro al store si se ha guardado bien y no existe ya.
if ( panelEdicion.storeAsociado.findExact(me.subconfig.modelPrefijoCampos + 'id',registroRegiso.get(me.subconfig.modelPrefijoCampos + 'id')) == -1) {
panelEdicion.storeAsociado.insert(0,registroRegiso);
//panelEdicion.storeAsociado.add(registro);
}
// Forzar cambios hechos en el store para que no lanze operaciones con el registro agregado
panelEdicion.storeAsociado.commitChanges();
} else {
// Si estamos modificando tambien hay que sobreescribir los valores del registroRegiso
// Asignamos los valores recibidos despues de guardar al registro del registro-iso
// solo se actualizaran los campos regiso_xxxx, o alguno adjunto re040102_ si existe definido en el modelo del doc
registroRegiso.set( registro.getData() );
// Forzar cambios hechos en el store para que no lanze operaciones con el registro modificado
panelEdicion.storeAsociado.commitChanges();
}

// Informar que hemos completado correctamente la tarea de guardar ficha para el multiguardar
me.completarMultiGuardar(-1, registroRegiso, registro, panelEdicion, true);

} else {
// Error al guardar
if (operation.hasException()) {
var mensajeError = operation.getError();
var iconoError = Ext.Msg.WARNING
} else {
var mensajeError = gt.dgettext('isoacademia','Error: No se han podido guardar los datos.');
var iconoError = Ext.Msg.ERROR
}

// Mostrar mensaje error
if (mainStatusBar) {
mainStatusBar.setStatus({
text: mensajeError,
iconCls: 'x-status-error',
//clear: true
clear: { useDefaults:true, anim: false }
});
}

Ext.Msg.show({
title: gt.dgettext('isoacademia','Guardar'),
msg: mensajeError,
buttons: Ext.Msg.OK,
icon: iconoError
});

// Informar que hemos completado con errores la tarea de guardar ficha para el multiguardar
me.completarMultiGuardar(-1, registroRegiso, registro, panelEdicion, false);
}
}
});
}
},


//
// Condiciones a comprobar antes de guardar
//
validarPreGuardar: function(panelEdicion, grid, formulario, registroRegiso, registroFicha ) {
var me = this;

// Con ventanas escoge abiertas no se puede guardar
var arrayCamposEscogeNombre = me.subconfig.preGuardar.arrayCamposEscogeNombre;
var campoEscoge;
if (arrayCamposEscogeNombre) {
for (var ceIndex=0; ceIndex<arrayCamposEscogeNombre.length; ceIndex++) {
campoEscoge = formulario.getForm().findField(arrayCamposEscogeNombre[ceIndex]);
if (campoEscoge) {
if ( campoEscoge.isDirty() ) {
campoEscoge.markInvalid( gt.dgettext('isoacademia','Debe introducir o seleccionar un valor válido.') );
return false;
}
}
}
}

// Con ventanas escoge abiertas no se puede guardar
var arrayVentanasEscoge = me.subconfig.preGuardar.arrayVentanasEscoge;
var ventanaEscoge;
if (arrayVentanasEscoge) {
for (var veIndex=0; veIndex<arrayVentanasEscoge.length; veIndex++) {
ventanaEscoge = grid[arrayVentanasEscoge[veIndex]];
if (ventanaEscoge) {
if ( ventanaEscoge.isVisible() ) {
Ext.Msg.show({
title: gt.dgettext('isoacademia','Guardar'),
msg: gt.dgettext('isoacademia','Tiene ventanas de selección abiertas. No puede guardar.'),
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
return false;
}
}
}
}

// Antes de guardar comprobar que no existen formularios anidados (da problemas porque getValues devuelve todos los anidados)
var arrayViewMantSubfichas = me.subconfig.preGuardar.arrayViewMantSubfichas;
var formAnidado;
if (arrayViewMantSubfichas) {
for (var faIndex=0; faIndex<arrayViewMantSubfichas.length; faIndex++) {
formAnidado = panelEdicion.down('isoacademia_view_' + arrayViewMantSubfichas[faIndex]);
if (formAnidado) {
Ext.Msg.show({
title: gt.dgettext('isoacademia','Guardar'),
msg: gt.dgettext('isoacademia','Está editando subfichas del registro iso. Acepte o cancele la edición de las subfichas que tiene abiertas, antes de guardar el registro iso.'),
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
return false;
}
}
}

// Revisar campos del formulario: obligatorios, etc...)
if (!formulario.getForm().isValid()) {
var camposFormulario = formulario.getForm().getFields();
var cadenaLabelsRevisar = '';
camposFormulario.each(function(campo, index, len) {
if (!campo.validate()) {
var etiqueta = '';
etiqueta = etiqueta + (campo.up('isoacademia_view_panelSubfichaBase',2) ? ' (' + gt.dgettext('isoacademia_view_panelSubfichaBase','Pestaña:') + ' ' + campo.up('isoacademia_view_panelSubfichaBase',2).title +') ' : '');
etiqueta = etiqueta + (campo.up('fieldcontainer',1) ? ' ' + campo.up('fieldcontainer',1).fieldLabel : '');
if (campo.fieldLabel) {
etiqueta = etiqueta + (Ext.String.trim(etiqueta).length>0 ? ' - ' : ' ') + (campo.fieldLabel ? campo.fieldLabel : '');
}
cadenaLabelsRevisar = cadenaLabelsRevisar + (cadenaLabelsRevisar.length>0 ? ', ' : '') + etiqueta;
}
});
Ext.Msg.show({
title: gt.dgettext('isoacademia','Guardar'),
msg: gt.dgettext('isoacademia','Revise los siguientes campos: ')+cadenaLabelsRevisar,
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
return false;
}

return true;
},

//
// Completar cada fase del multiguardar y lanzar la siguiente
//
completarMultiGuardar: function(multiguardarIndex, registroRegiso, registroFicha, panelEdicion, success) {
var me = this;
var grid = panelEdicion.up('isoacademia_view_registrosIso_mant').down('isoacademia_view_registrosIso_mantGrid[name="gridRegistrosIso"]');
var siguienteProcesoIndex = null;
var siguienteProcesoConfig = null;

// if (multiguardarIndex == (-1) ) {
// el menos uno se usa para completar el guardar principal de la ficha, que no se incluye en el array multiguardar
// porque se debe hacer siempre
//}

if (success) {
siguienteProcesoIndex = multiguardarIndex + 1
// comprobar si hay más procesos que completar. Si el index completado esta en el rango de elementos de los procesosMultiGuardar
if (siguienteProcesoIndex < me.procesosMultiGuardar.length) {
siguienteProcesoConfig = me.procesosMultiGuardar[siguienteProcesoIndex];

switch (siguienteProcesoConfig.tipo) {
// sincronizar una tabla de subfichas
case 'subfichasSync':
me.syncSubfichas(siguienteProcesoIndex, siguienteProcesoConfig, registroRegiso, registroFicha, panelEdicion);
break;
// ejecutar un método personalizado
case 'personalizado':
if (Ext.isFunction(siguienteProcesoConfig.metodo)) {
// Llamar al método en el scope (this / me) añadiendo .bind(scope) al final
siguienteProcesoConfig.metodo.bind(me)(siguienteProcesoIndex, siguienteProcesoConfig, registroRegiso, registroFicha, panelEdicion);
}
break;
}

} else {
// Ya no hay mas procesos que completar
// Lanzar los procesos posteditar
me.postEditar(registroRegiso, registroFicha, panelEdicion);
}
}
},

//
// Lanzar los procesos del post-editar
//
postEditar: function(registroRegiso, registroFicha, panelEdicion) {
var me = this;

// Iniciar tabla de configuraciones del proceso posteditar
me.procesosPostEditar = me.subconfig.procesosPostEditar;

// Lanzar el primer proceso del post editar, i si no hay ninguno se cerrará la edición
me.completarPostEditar(-1, registroRegiso, registroFicha, panelEdicion, true);
},

//
// Completar cada fase del post-editar y lanzar la siguiente
//
completarPostEditar: function(posteditarIndex, registroRegiso, registroFicha, panelEdicion, success) {
var me = this;
var grid = panelEdicion.up('isoacademia_view_registrosIso_mant').down('isoacademia_view_registrosIso_mantGrid[name="gridRegistrosIso"]');
var siguienteProcesoIndex = null;
var siguienteProcesoConfig = null;

// if (posteditarIndex == (-1) ) {
// el menos uno se usa para lanzar el primer proceso
//}

if (success) {
siguienteProcesoIndex = posteditarIndex + 1
// comprobar si hay más procesos que completar. Si el index completado esta en el rango de elementos de los procesosPostEditar
if (siguienteProcesoIndex < me.procesosPostEditar.length) {
siguienteProcesoConfig = me.procesosPostEditar[siguienteProcesoIndex];

switch (siguienteProcesoConfig.tipo) {
// ejecutar un método personalizado
case 'personalizado':
if (Ext.isFunction(siguienteProcesoConfig.metodo)) {
// Llamar al método en el scope (this / me) añadiendo .bind(scope) al final
siguienteProcesoConfig.metodo.bind(me)(siguienteProcesoIndex, siguienteProcesoConfig, registroRegiso, registroFicha, panelEdicion);
}
break;
}

} else {
// Ya no hay mas procesos que completar

// Cerrar el panel de edicion
Ext.destroy(panelEdicion);
// Refrescar el grid para que muestre valores actualizados del registro
grid.getView().refresh();
// Dejamos seleccionado en la lista el registro que acabamos de guardar
grid.getSelectionModel().deselectAll( false );
if ( grid.getStore().findRecord('regiso_id',registroRegiso.get('regiso_id'),0,false,false,true) ) {
grid.getSelectionModel().select([registroRegiso], false, false);
}
}
}
},

//
// Sincronizar subfichas (hace los destroy, create, update) de forma asincrona.
//
// Ejemplo config: {
// tipo: 'subfichasSync',
// nombre: 're040102Lin',
// descripcionMinus: gt.dgettext('isoacademia','línea'),
// descripcionMinusPlural: gt.dgettext('isoacademia','líneas'),
// descripcionMayus: gt.dgettext('isoacademia','Línea'),
// descripcionMayusPlural: gt.dgettext('isoacademia','Líneas'),
// viewGridNombre: 're040102Lin.mantGrid',
// viewGridAlias: 're040102Lin_mantGrid',
// modelNombre: 're040102lin',
// modelPrefijoCampos: 're040102lin_',
// modelCampoEnlace: 're040102lin_recab_id'
// }
syncSubfichas: function(multiguardarIndex, config, registroRegiso, registroFicha, panelEdicion) {
var me = this;
var ficha_id = registroFicha.get(me.subconfig.modelPrefijoCampos + 'id');
var gridSubfichas = panelEdicion.down('isoacademia_view_' + config.viewGridAlias);
var storeSubfichas = gridSubfichas.getStore();
var mainStatusBar = panelEdicion.up('isoacademia_view_main').down('isoacademia_view_mainStatusBar[name="mainStatusBar"]');

// Comprobar si hay registros que actualizar
if ( !(storeSubfichas.getModifiedRecords().length>0 || storeSubfichas.getRemovedRecords().length>0) ) {
// Informar que hemos completado correctamente la tarea de guardar las subfichas para el multiguardar
me.completarMultiGuardar(multiguardarIndex, registroRegiso, registroFicha, panelEdicion, true);
return true;
}

// Si la subficha era nueva y aun no se habia guardado por primera vez hay que poner el ficha_id en los campos de enlace
if ( panelEdicion.modo=="nuevo" ) {
var regsModificadosoNuevos = storeSubfichas.getModifiedRecords();
for (var i=0; i<regsModificadosoNuevos.length; i++) {
regsModificadosoNuevos[i].set(config.modelCampoEnlace,ficha_id);
}
var regsBorrados = storeSubfichas.getRemovedRecords(); // No haria falta ponerlo en los borrados.
for (var i=0; i<regsBorrados.length; i++) {
regsBorrados[i].set(config.modelCampoEnlace,ficha_id);
}
}

// Mostrar "guardando" en barra de estado
if (mainStatusBar) {
mainStatusBar.setStatus({
text: gt.dgettext('isoacademia','Guardando registro ... ') + ' ' + config.descripcionMayusPlural + ' ...',
iconCls: 'x-status-busy',
clear: false
});
}
// Mostrar mascara
panelEdicion.getEl().mask(gt.dgettext('isoacademia','Guardando') + ' ' + config.descripcionMinusPlural + ' ...');


// Ejecutar el sync del store (lanza en modo batch todos los destroy, create y update a través del proxy de forma asincrona)
storeSubfichas.sync({

// operaciones crud todas correctas
success: function(batch, options) {
// Limpiar barra de estado
if (mainStatusBar) {
mainStatusBar.clearStatus({ useDefaults:true, anim: false });
}
panelEdicion.getEl().unmask();
// Informar que hemos completado correctamente la tarea de guardar las subfichas para el multiguardar
me.completarMultiGuardar(multiguardarIndex, registroRegiso, registroFicha, panelEdicion, true);
},

// Alguna operacion crud con fallos
failure: function(batch, options) {
// Limpiar barra de estado
if (mainStatusBar) {
mainStatusBar.clearStatus({ useDefaults:true, anim: false });
}
panelEdicion.getEl().unmask();

// Cadena con el mensaje de error a mostrar
var mensajeError = null;

// Recorrer resultados de las operaciones crud generadas automaticamente por sync()
for (var i=0; i<batch.operations.length; i++) {
var operacion = batch.operations[i];
// Error en la operacion (solo puede ser create, update o destroy)
if (operacion.hasException()) {
// Obtener registros que han generado la operacion.
var registrosOperacion = operacion.getRecords();
// Si solo se mandó un registro el único error posible no viene en un array sino en un string directo
if (registrosOperacion.length==1 || (typeof operacion.getError())=="string") {
var registroOperacion = registrosOperacion[0];
if (registroOperacion) {
// Si la accion era borrar y ha fallado volver a poner el registro borrado en el store
if (operacion.action=='destroy') {
storeSubfichas.add(registroOperacion);
}
// Montar cadena mensaje de error
mensajeError = (mensajeError==null ? '' : mensajeError + '<br />') + config.descripcionMayus + ': ' + registroOperacion.get(config.modelPrefijoCampos + 'id') + '<br />' + operacion.getError();
}

} else {

// Si se mandaron multiples registros aunque solo haya un error viene en un array con 2 partes
// php $respuesta['message']['errores'] array de mensajes de error
// php $respuesta['message']['data'] registros refrescados despues de procesar o con el valor original si han fallado
// obtener array de mensajes de error si los hay (en sync batch mode sera un array con estas keys 'indexRegOpe', 'errorNum' , 'errorMsg', 'message'
var mensajesErrorOperacion = operacion.getError().errores;

// Montar cadena error y recuperar borrados que han fallado
if (mensajesErrorOperacion==null || mensajesErrorOperacion.length<=0) {
mensajeError = (mensajeError==null ? '' : mensajeError + '<br />') + gt.dgettext('isoacademia','Error al guardar') + ' ' + config.descripcionMinusPlural +'. ('+operacion.action+')';
} else {
// Bucle para montar el mensaje de error
for (var j=0; j<mensajesErrorOperacion.length; j++) {
if (typeof mensajesErrorOperacion[j]['indexRegOpe'] != "undefined") {
if ( mensajesErrorOperacion[j]['indexRegOpe']>=0 && mensajesErrorOperacion[j]['indexRegOpe']<registrosOperacion.length) {
// Coger el registro original que corresponde al error recibido
var registroOperacion = registrosOperacion[ mensajesErrorOperacion[j]['indexRegOpe'] ];
if (registroOperacion) {
// Si la accion era borrar y ha fallado volver a poner el registro borrado en el store
if (operacion.action=='destroy') {
storeSubfichas.add(registroOperacion);
}
// Montar cadena mensaje de error
mensajeError = (mensajeError==null ? '' : mensajeError + '<br />') + config.descripcionMayus + ': ' + registroOperacion.get(config.modelPrefijoCampos + 'id') + '<br />' + mensajesErrorOperacion[j]['message'];
}
}
}
}
}


// Aunque haya errores actualizamos los otros registros en create y update
// que si hayan ido bien y han devuelto el data refrescado
// php $respuesta['message']['data'] registros refrescados despues de procesar o con el valor original si han fallado
var dataRespuestaOperacion = operacion.getError().data;
if (dataRespuestaOperacion) {
var registrosRespuestaOperacion = storeSubfichas.getProxy().getReader().read(dataRespuestaOperacion).records;
if ((operacion.action=='create' || operacion.action=='update') && registrosRespuestaOperacion) {
// Recorremos todos los registros originales enviados en la operacion para ver si se pueden actualizar
// con su homonimo recibido del php
for (var r=0; r<registrosOperacion.length; r++) {
// Mirar si el index r no esta entre los registros que tiene error
var regConError = false;
for (var j=0; j<mensajesErrorOperacion.length; j++) {
if ( mensajesErrorOperacion[j]['indexRegOpe']==r) {
regConError = true;
break;
}
}
if (!regConError) {
var registroOperacion = registrosOperacion[r];
var registroRespuestaOperacion = registrosRespuestaOperacion[r];
if (registroOperacion && registroRespuestaOperacion) {
// Si el registro original no es nuevo (phantom), asegurarse que los ids coinciden entre el registro original enviado y el recibido.
if(registroOperacion.getId() === registroRespuestaOperacion.getId() || registroOperacion.phantom ) {
registroOperacion.copyFrom(registroRespuestaOperacion);
registroOperacion.commit();
}
}
}
}
}
} // Fin commits

} // Fin varios registros
} // Fin tiene algun error operacion
} // Fin bucle operaciones


// Se muestra un solo mensaje de error con los textos de todas las operaciones
if (mensajeError) {
Ext.Msg.show({
title: config.descripcionMayusPlural,
msg: mensajeError,
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
}

// Puesto que si falla algun borrar se reagrega el registro al store, limpiamos el array de borrados para el siguiente sync.
storeSubfichas.removed = [];

// Informar que hemos completado con errores la tarea de guardar las subfichas para el multiguardar
me.completarMultiGuardar(multiguardarIndex, registroRegiso, registroFicha, panelEdicion, false);
}
});

},

//
// Refrescar totales de un registro ya existente o acabado de guardar
//
refrescarTotalesRegistro: function(posteditarIndex, config, registroRegiso, registroFicha, panelEdicion ) {
var me = this;
var grid = panelEdicion.up('isoacademia_view_registrosIso_mant').down('isoacademia_view_registrosIso_mantGrid[name="gridRegistrosIso"]');

if (registroRegiso && registroFicha) {

// Mostrar "refrescando" en barra de estado
var mainStatusBar = grid.up('isoacademia_view_main').down('isoacademia_view_mainStatusBar[name="mainStatusBar"]');
if (mainStatusBar) {
mainStatusBar.setStatus({
text: gt.dgettext('isoacademia','Refrescando totales del registro ... ') + registroFicha.get(me.subconfig.modelPrefijoCampos + 'id'),
iconCls: 'x-status-busy',
clear: false
});
}
// Mostrar mascara
panelEdicion.getEl().mask(gt.dgettext('isoacademia','Refrescando totales del registro ...'));

// Ejecutar funcion extdirect para refrescar el registroFicha que corresponde al id solicitado para editar
// Asi cogemos los datos mas recientes para editar
// Parámetros que enviamos id, guid, empresa_id
// Hay que crearlo así para poder poner los nombres con los prefijos configurables
var parametrosRefrescarDirect = {}
parametrosRefrescarDirect[me.subconfig.modelPrefijoCampos + 'id'] = registroFicha.get(me.subconfig.modelPrefijoCampos + 'id');
parametrosRefrescarDirect[me.subconfig.modelPrefijoCampos + 'guid'] = registroFicha.get(me.subconfig.modelPrefijoCampos + 'guid');
if ( registroFicha.fields.indexOfKey(me.subconfig.modelPrefijoCampos + 'empresa_id') != (-1) ) {
parametrosRefrescarDirect[me.subconfig.modelPrefijoCampos + 'empresa_id'] = registroFicha.get(me.subconfig.modelPrefijoCampos + 'empresa_id');
}

//Ext.isoacademiaDirect.isoacademia_rexxxxxx.getRexxxxxxTotalesPorId({
window["Ext"]["isoacademiaDirect"][me.subconfig.nombreExtDirect][config.directMetodoPhpNombre](

// pasamos los parametros
parametrosRefrescarDirect

, function(provider, response) {

panelEdicion.getEl().unmask();

// Cuando llega la respuesta asincrona, entonces editamos el registroFicha si ha ido bien la carga del refresco
if (response.result.success) {
// Comprobar que nos llega el mismo id que hemos pedido
if (response.result.data[0]) {

// Limpiar barra de estado
if (mainStatusBar) {
mainStatusBar.clearStatus({ useDefaults:true, anim: false });
}

if (response.result.data[0][me.subconfig.modelPrefijoCampos + 'id']==registroFicha.get(me.subconfig.modelPrefijoCampos + 'id')) {
// Pasar los datos de los totales recibidos al registroFicha que estaba en el store
var arrayCamposRefrescar = config.arrayCamposRefrescar;
var arrayCamposNoRefrescar = config.arrayCamposNoRefrescar;

// Refrescar solo algunos campos recibidos por el Ext.Direct
if ((arrayCamposRefrescar && arrayCamposRefrescar.length>0) || (arrayCamposNoRefrescar && arrayCamposNoRefrescar.length>0)) {
for( var campoRecibidoNombre in response.result.data[0] ) {
// Mirar si es un campo a refrescar
if (arrayCamposRefrescar.length==0 || arrayCamposRefrescar.indexOf(campoRecibidoNombre) != (-1)) {
// Mirar si es un campo a NO refrescar
if (arrayCamposNoRefrescar.length==0 || arrayCamposNoRefrescar.indexOf(campoRecibidoNombre) == (-1)) {
// Refrescar
registroFicha.set( campoRecibidoNombre, response.result.data[0][campoRecibidoNombre] );
}
}
}
} else {
// Refrescar todos los campos recibidos por el Ext.Direct
registroFicha.set( response.result.data[0] );
}
registroFicha.commit();

// Informar que hemos completado correctamente la tarea refrescar los totales para el posteditar
me.completarPostEditar(posteditarIndex, registroRegiso, registroFicha, panelEdicion, true);
return true;
}
}
}

// Mostrar mensaje error
if (mainStatusBar) {
mainStatusBar.setStatus({
text: gt.dgettext('isoacademia','No se han podido refrescar los totales del registro.'),
iconCls: 'x-status-error',
clear: {anim: false, useDefaults: true }
});
}

// Mostrar mensaje que no se puede editar el registro
Ext.Msg.show({
title: gt.dgettext('isoacademia','Editar'),
msg: gt.dgettext('isoacademia','No se han podido refrescar los totales del registro.<br />Vuelva a refrescar la lista.'),
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.WARNING,
fn: function(btn, text, opt) {
// nada
}
})

// Informar que hemos completado con errores la tarea refrescar los totales para el posteditar
me.completarPostEditar(posteditarIndex, registroRegiso, registroFicha, panelEdicion, false);
return false;
}
);
}
},


//
// Función para forzar o no forzar los campos como obligatorios
//
camposDinamicos: function( panelEdicion, formulario ) {
//var me = this;
//var formBasic = formulario.getForm();
//var ctrlCamposDinamicos = isoacademiaApp.getController('camposDinamicos');

//Ext.suspendLayouts();
//Ext.resumeLayouts(true);
}

});




//@charset UTF-8

Ext.define('isoacademia.controller.re040102.mant', {
// Controller que hereda del patron rexxxxxx.mant
extend: 'isoacademia.controller.rexxxxxx.mant',

models:[
're040102'
],
stores:[
're040102'
],
views: [
're040102.mantEdicion'
],

init: function() {
var me = this;

// Ejecutar método del parent
this.callParent(arguments);

me.control({
'isoacademia_view_re040102_mantEdicion' : {
afterrender: me.onRenderFichaEdicion,
guardar: me.onGuardarAction,
cancelar: me.onCancelarAction
}
});

// Definir los nombres, configuraciones y otros valores del sub-controller
me.subconfig = Ext.apply(me.subconfig || {}, {
nombreMinus: 're040102',
nombreMinusPlural: 're040102',
nombreMayus: 'Re040102',
nombreMayusPlural: 'Re040102',

nombreExtDirect: 'isoacademia_re040102',
directMetodoClonarPhpNombre: 'clonarRe040102',

modelNombre: 're040102',
modelPrefijoCampos: 're040102_',
storeNombre: 're040102',

viewMantEdicion: 're040102.mantEdicion',
viewMantEdicionAlias: 're040102_mantEdicion',
formularioObjNombre: 'formularioRe040102',

// Nombre del campo que se muestra al pedir confirmación para borrar
confBorrarMostrarCampo: 'regiso_id',

// validaciones para el pre-guardar
preGuardar: {
arrayCamposEscogeNombre: [], // Nombres de los campos que corresponden a un "escoge" en el formulario principal
arrayVentanasEscoge: [], // Ventanas escoge definidas en el grid principal
arrayViewMantSubfichas: ['re040102Lin_mantEdicion'] // Alias de los mantenimientos de las subfichas anidadas a la ficha principal
},

// Procesos que se ejecutan conscutivamente después de guardar (save) la ficha principal
procesosMultiGuardar: [{
nombre: 're040102Lin',
tipo: 'subfichasSync',
descripcionMinus: gt.dgettext('isoacademia','línea'),
descripcionMinusPlural: gt.dgettext('isoacademia','líneas'),
descripcionMayus: gt.dgettext('isoacademia','Línea'),
descripcionMayusPlural: gt.dgettext('isoacademia','Líneas'),
viewGridNombre: 're040102Lin.mantGrid',
viewGridAlias: 're040102Lin_mantGrid',
modelNombre: 're040102lin',
modelPrefijoCampos: 're040102lin_',
modelCampoEnlace: 're040102lin_recab_id'
}],

// Procesos que se ejecutan conscutivamente después de guardar correctamente todos los datos del multiguardar
// También se lanza al clicar cancelar.
procesosPostEditar: []

}, me.subconfig);
},

refs: [
],

//
// Override del método en la classe del controller parent
// Función para forzar o no forzar los campos como obligatorios
//
camposDinamicos: function( panelEdicion, formulario ) {
var me = this;
var formBasic = formulario.getForm();
var ctrlCamposDinamicos = isoacademiaApp.getController('camposDinamicos');

// Ejecutar método del parent (si no se quiere ejecutar lo del parent, se puede omitir)
this.callParent(arguments);

// Valores de los campos del formulario que afectan a los dinámicos
// var regiso_contacto_id = formBasic.findField('regiso_contacto_id').getValue();
// var hayPdfAceptado = (formBasic.findField('hayPdfAceptado').getValue() == 'true'); // Ojo es un string.

Ext.suspendLayouts();
// Si hay pdf aceptado mostrar boton "quitar pdf" / y el "ver imprimir"
// formulario.down('button[name="botonQuitarPdf"]').setVisible( hayPdfAceptado );
// formulario.down('button[name="botonImprimirPdf"]').setVisible( hayPdfAceptado );
// Si hay pdf aceptado boton subir tiene que poner "cambiar"
// formulario.down('button[name="botonUploaderPdf"]').setText( ( hayPdfAceptado ? gt.dgettext('isoacademia','Cambiar PDF aceptado...') : gt.dgettext('isoacademia','Subir PDF aceptado...') ));

// Campos obligatorios y no obligatorios segun condiciones.
// setCampoObligatorio (params) formBasic, campoNombre, obligatorio, autoOcultar
// ctrlCamposDinamicos.setCampoObligatorio(formBasic, 'regiso_alaattde', regiso_contacto_id<=0, false );

// Campos editables y no editables segun condiciones.
// Los campos que son siempre editables no hace falta marcarlos
// setCampoEditable (params) formBasic, campoNombre, editable, autoOcultar

// // Si es una RE040102 confirmada no dejamos editar campos
// ctrlCamposDinamicos.setCampoEditable(formBasic, 'escoge_re040102_serie_codigo', !presupuestoConfirmada, false );

Ext.resumeLayouts(true);
}

});




//@charset UTF-8

Ext.define('isoacademia.controller.re040103.mant', {
// Controller que hereda del patron rexxxxxx.mant
extend: 'isoacademia.controller.rexxxxxx.mant',

models:[
're040103'
],
stores:[
're040103'
],
views: [
're040103.mantEdicion'
],

init: function() {
var me = this;

// Ejecutar método del parent
this.callParent(arguments);

me.control({
'isoacademia_view_re040103_mantEdicion' : {
afterrender: me.onRenderFichaEdicion,
guardar: me.onGuardarAction,
cancelar: me.onCancelarAction
}
});

// Definir los nombres, configuraciones y otros valores del sub-controller
me.subconfig = Ext.apply(me.subconfig || {}, {
nombreMinus: 're040103',
nombreMinusPlural: 're040103',
nombreMayus: 'Re040103',
nombreMayusPlural: 'Re040103',

nombreExtDirect: 'isoacademia_re040103',
directMetodoClonarPhpNombre: 'clonarRe040103',

modelNombre: 're040103',
modelPrefijoCampos: 're040103_',
storeNombre: 're040103',

viewMantEdicion: 're040103.mantEdicion',
viewMantEdicionAlias: 're040103_mantEdicion',
formularioObjNombre: 'formularioRe040103',

// Nombre del campo que se muestra al pedir confirmación para borrar
confBorrarMostrarCampo: 'regiso_id',

// validaciones para el pre-guardar
preGuardar: {
arrayCamposEscogeNombre: [], // Nombres de los campos que corresponden a un "escoge" en el formulario principal
arrayVentanasEscoge: [], // Ventanas escoge definidas en el grid principal
arrayViewMantSubfichas: ['re040103Lin_mantEdicion'] // Alias de los mantenimientos de las subfichas anidadas a la ficha principal
},

// Procesos que se ejecutan conscutivamente después de guardar (save) la ficha principal
procesosMultiGuardar: [{
nombre: 're040103Lin',
tipo: 'subfichasSync',
descripcionMinus: gt.dgettext('isoacademia','línea'),
descripcionMinusPlural: gt.dgettext('isoacademia','líneas'),
descripcionMayus: gt.dgettext('isoacademia','Línea'),
descripcionMayusPlural: gt.dgettext('isoacademia','Líneas'),
viewGridNombre: 're040103Lin.mantGrid',
viewGridAlias: 're040103Lin_mantGrid',
modelNombre: 're040103lin',
modelPrefijoCampos: 're040103lin_',
modelCampoEnlace: 're040103lin_recab_id'
}],

// Procesos que se ejecutan conscutivamente después de guardar correctamente todos los datos del multiguardar
// También se lanza al clicar cancelar.
procesosPostEditar: []

}, me.subconfig);
},

refs: [
],

//
// Override del método en la classe del controller parent
// Función para forzar o no forzar los campos como obligatorios
//
camposDinamicos: function( panelEdicion, formulario ) {
var me = this;
var formBasic = formulario.getForm();
var ctrlCamposDinamicos = isoacademiaApp.getController('camposDinamicos');

// Ejecutar método del parent (si no se quiere ejecutar lo del parent, se puede omitir)
this.callParent(arguments);

//Ext.suspendLayouts();
//
//Ext.resumeLayouts(true);
}

});


my app.js file is this one:



//@charset UTF-8

// Cargador dinamico
//<debug>
Ext.Loader.setConfig({
enabled: true,
disableCaching: false,
paths: {
// Cesi.ux (Controles propios cesi)
'Cesi.ux': '../../libs/extjs_cesi/Cesi/ux',
// Extjs (la carpeta ux normalmente viene en el codigo fuente de sencha dentro de examples)
// Plugins y extensiones extjs
'Ext.ux': '../../libs/ext/src/ux',
// Extjs
'Ext': '../../libs/ext/src'
}
});
//</debug>

Ext.require('Ext.app.Application');
Ext.require('Ext.direct.*');
Ext.require('Ext.data.*');
Ext.require('Ext.tip.*');
Ext.require('Ext.window.MessageBox');
Ext.require('Ext.util.Format');
Ext.require('Ext.layout.container.Border');
Ext.require('Ext.chart.theme.Base');

// Requires forzados para la compilacion o Ejecución en desarrollo
Ext.require('Ext.toolbar.Paging');
Ext.require('Cesi.ux.layout.component.field.BoxSelectField');
Ext.require('Cesi.ux.form.field.BoxSelect');

// Variables globales
var isoacademiaApp;
var directProvider;

// Funcion que se ejecuta cuando se ha cargado todo lo necesario de las extjs.
Ext.onReady(function(){

// Arreglar algunos bugs en las traducciones de botones Extjs
// Forzar idioma botones messagebox (bug ext)
if (Ext.MessageBox) {
Ext.MessageBox.msgButtons['ok'].text = Ext.MessageBox.buttonText.ok;
Ext.MessageBox.msgButtons['cancel'].text = Ext.MessageBox.buttonText.cancel;
Ext.MessageBox.msgButtons['yes'].text = Ext.MessageBox.buttonText.yes;
Ext.MessageBox.msgButtons['no'].text = Ext.MessageBox.buttonText.no;
}

// Cargar el proveedor de Ext.Direct con la configuracion de API
directProvider = Ext.direct.Manager.addProvider(Ext.app.isoacademia_REMOTING_API);

// Separador decimal y de millares
Ext.util.Format.decimalSeparator = '.';
Ext.util.Format.thousandSeparator = ',';

// Definir el Theme para los graficos
Ext.define('Ext.chart.theme.isoacademia_theme', {
extend: 'Ext.chart.theme.Base',
constructor: function(config) {
this.callParent([Ext.apply({
colors: ['#94AE0A', '#115FA6', '#A61120','#F0A50A','#D54679','#FFCC2B','#A66111']
}, config)]);
}
});

// Definir la MVC app principal (isoacademiaApp)
// Dominio de las clases js = isoacademia.xxxxxx
Ext.application({
name: 'isoacademia',
autoCreateViewport: false,
enableQuickTips: true,
appFolder: 'app',

controllers: [
// Controladores isoAcademia
'main', 'mainMenu', 'mainMenuEmpresa', 'mainStatusBar', 'listadoPartes', 'gridBase',
'camposDinamicos',
'preimpresos.escoge',
'empresas.escoge',
'contactos.escoge',
'direcciones.escoge',
'registrosIso.mant', 'registrosIso.filtrosGrid',
'registrosIso.imprimir',
'rexxxxxx.mant', 'rexxxxxxSubficha.mant', 'rexxxxxx.imprimir',
're040102.mant', 're040102Lin.mant', 're040102.imprimir',
're040103.mant', 're040103Lin.mant', 're040103.imprimir',
'configuracion.mant',
'configuracionEmpresas.mant',
'contadoresEmpresas.mant'
],

launch: function() {
var me = this;

// Guardar el objeto aplicacion en una variable global
isoacademiaApp = me;

// Añadir un listener al direct manager para que analice todos los datos que llegan y
// si vienen con el requiereLogin = true, abrir ventana de login.
directProvider.on({
data: function( provider, e, eOpts ){
if (e.result) {
if (e.result.requiereLogin) {
// Mostrar aviso para que haga login en eSInube
Ext.MessageBox.show({
title: gt.dgettext('isoacademia','Sesión.'),
msg: gt.dgettext('isoacademia','Debe iniciar sesión en eSInube.<br />Haga click en OK para cargar pantalla de entrada.'),
buttons: Ext.MessageBox.OK,
closable: false,
icon: Ext.window.MessageBox.WARNING,
modal: true,
fn: function( buttonId, text, opt) {
// Volver a cargar la pagina principal del esinube
window.location = '../../';
}
});
}
}
},
scope: this
});


// Comprobar si es necesario hacer login
Ext.isoacademiaDirect.isoacademia_sesiones.requiereLogin(function(response, event) {

if (response.requiereLogin) {
//winLogin = me.getView('login').create();
//winLogin.show();
// Mostrar aviso para que haga login en eSInube
Ext.MessageBox.show({
title: gt.dgettext('isoacademia','Sesión.'),
msg: gt.dgettext('isoacademia','Debe iniciar sesión en eSInube.<br />Haga click en OK para cargar pantalla de entrada.'),
buttons: Ext.MessageBox.OK,
closable: false,
icon: Ext.window.MessageBox.WARNING,
modal: true,
fn: function( buttonId, text, opt) {
// Volver a cargar la pagina principal del esinube
window.location = '../../';
}
});

} else {

// Añadir eventos a la aplicacion antes y despues de los pasos iniciales
me.addEvents('prePasosIniciales','postPasosIniciales');

// Mostrar máscara
Ext.getBody().mask(gt.dgettext('isoacademia','Cargando empresas autorizadas ...'));

// Asignar el store en la app para que siempre tengamos disponibles todos los tipos de registros iso
me.storeTiposRegisoDisponibles = Ext.create('isoacademia.store.tiposRegiso', {
storeId: Ext.id(),
autoLoad: false,
pageSize: -1
});
// Cargar empresas en el store
// Aunque el load será asíncrono se supone que dará tiempo suficiente antes de mostrar ninguna pantalla
me.storeTiposRegisoDisponibles.load({
//callback: function(records, operation, success) {
//}
});


// Al ser una aplicacion multiempresa, antes de ejecutar los pasos iniciales ni mostrar nada,
// hay que asegurarse que se ha cargado el store con las empresas disponibles
// Asignar el store para poder tener las empresas disponibles (Forzamos la creación de un objeto nuevo)
me.storeEmpresasDisponibles = Ext.create('isoacademia.store.empresasEscoge', {
storeId: Ext.id(),
autoLoad: false,
pageSize: -1
});

// Cargar empresas en el store
me.storeEmpresasDisponibles.load({
callback: function(records, operation, success) {
// Quitar máscara
Ext.getBody().unmask();

// Si se ha cargado correctamente, hacer los pasos iniciales
// Comprobar que al menos tiene una empresa permitida
if (success && records.length>0) {

// Evento previo a los pasos iniciales
if (me.fireEvent('prePasosIniciales')) {

//
// Ejecutar los pasos iniciales al entrar (incluye la creacion del view principal)
//
me.getController('main').pasosIniciales( me );

// Evento de pasos iniciales acabados
me.fireEvent('postPasosIniciales');
}

} else {
// Mostrar mensaje si no tiene ninguna empresa permitida para operar con esta aplicacion
Ext.MessageBox.show({
title: gt.dgettext('isoacademia','Empresas autorizadas.'),
msg: gt.dgettext('isoacademia','Lo sentimos, pero su cuenta de usuario, no tiene permiso para operar con ninguna empresa en esta aplicación.')
+ '<br />' + gt.dgettext('isoacademia','Compruebe también, que en el sistema existe al menos una empresa creada, y que dicha empresa tiene permisos para operar con esta aplicación.')
+ '<br />' + gt.dgettext('isoacademia','No puede entrar a la aplicación.'),
buttons: Ext.MessageBox.OK,
icon: Ext.MessageBox.WARNING,
closable: false,
icon: Ext.window.MessageBox.WARNING,
modal: true,
fn: function(btn, text, opt) {
// Cerrar ventana del iframe aplicacion
if (parent) {
if (parent.esinubeApp) {
var panelAplicaciones = parent.esinubeApp.escritorioPrincipal.down('panel[region=center][name="zonaEscritorio"]');
if (panelAplicaciones) {
var appsAbiertas = panelAplicaciones.query('esinube_view_windowIframe');
for (var i=0; i<appsAbiertas.length; i++) {
// COmprobar si el nombre del frame coincide con el window actual de la app
if ( appsAbiertas[i].down('[name="iframewebexterna"]').frameName == window.name ) {
// Cerrar ventana
appsAbiertas[i].close();
}
}
}
}
}
}
});
}

// Ya podemos destruir el store de empresas disponibles (no lo necesitamos mas, las empresas estan en el menu)
if (!me.storeEmpresasDisponibles.isDestroyed) {
if (me.storeEmpresasDisponibles.storeId) {
me.storeEmpresasDisponibles.destroyStore();
Ext.data.StoreManager.unregister(me.storeEmpresasDisponibles);
}
delete me.storeEmpresasDisponibles;
}

}
});
}
});
}

});

});

maneljn
20 Feb 2015, 3:40 AM
I have solved my problem with this workaround. But i don't know if i'm doing it correctly.
Instead of extend my 2 controllers i use "mixins" in the final controllers to add the base controller functionality.

With this solution i can mantain each final controller with its own values in "subconfig" property.

Now i have some questions , for expert programmers:

1.- Does i have to extend the base controller (rexxxxxx.mant = the one that will be added via mixins in the 2 final controllers) from 'Ext.app.Controller' or i don't have to extend from nothing ?

2.- Can i write some models in base controller (rexxxxxx.mant) models: [], and also write more models in re040103.mant ?? They will rest both ?

3.- Does i have to add the base controller (rexxxxxx.mant) in app.js controllers[] ?? Or just add the 2 final controllers: re040102.mant and re040103.mant ??


Base controller:



//@charset UTF-8

// Controller para extender al crear los controllers de cada tipo de documento registro iso , p.ex. re040102.mant
// Se añadirá la funcionalidad del rexxxxxx.mant a los subcontrollers por medio de "mixins"
Ext.define('isoacademia.controller.rexxxxxx.mant', {
extend: 'Ext.app.Controller',

models:[
'tipoRegiso',
'rexxxxxx'
// El resto, se definen en cada controller extendido
],
stores:[
'tiposRegiso'
// El resto, se definen en cada controller extendido
],
views: [
'rexxxxxx.edicionCamposComunesCab',
'rexxxxxx.edicionCamposInfoRegistro'
// El resto, se definen en cada controller extendido
],

// Se definen en cada controller extendido
// init: function() {
// var me = this;
//},

// refs: [
// ],

// Definir los nombres, configuraciones y otros valores del sub-controller
// Se definen en cada controller extendido
// Ejemplo:
// // Definir los nombres, configuraciones y otros valores del sub-controller
// subconfig: {
// nombreMinus: 're040102',
// nombreMinusPlural: 're040102',
// nombreMayus: 'Re040102',
// nombreMayusPlural: 'Re040102',
//
// nombreExtDirect: 'isoacademia_re040102',
// directMetodoClonarPhpNombre: 'clonarRe040102',
//
// modelNombre: 're040102',
// modelPrefijoCampos: 're040102_',
// storeNombre: 're040102',
//
// viewMantEdicion: 're040102.mantEdicion',
// viewMantEdicionAlias: 're040102_mantEdicion',
// formularioObjNombre: 'formularioRe040102',
//
// // Nombre del campo que se muestra al pedir confirmación para borrar
// confBorrarMostrarCampo: 'regiso_id',
//
// // validaciones para el pre-guardar
// preGuardar: {
// arrayCamposEscogeNombre: ['escoge_cto_nombre_fiscal'],
// arrayVentanasEscoge: ['windowEscogeContacto'],
// arrayViewMantSubfichas: ['re040102Lin_mantEdicion']
// },
//
// // Procesos que se ejecutan conscutivamente después de guardar (save) la ficha principal
// procesosMultiGuardar: [{
// nombre: 're040102Lin',
// tipo: 'subfichasSync',
// descripcionMinus: gt.dgettext('isoacademia','línea'),
// descripcionMinusPlural: gt.dgettext('isoacademia','líneas'),
// descripcionMayus: gt.dgettext('isoacademia','Línea'),
// descripcionMayusPlural: gt.dgettext('isoacademia','Líneas'),
// viewGridNombre: 're040102Lin.mantGrid',
// viewGridAlias: 're040102Lin_mantGrid',
// modelNombre: 're040102lin',
// modelPrefijoCampos: 're040102lin_',
// modelCampoEnlace: 're040102lin_recab_id'
// }],
//
// // Procesos que se ejecutan conscutivamente después de guardar correctamente todos los datos del multiguardar
// // También se lanza al clicar cancelar.
// procesosPostEditar: [{
// nombre: 'refrescarTotales',
// tipo: 'personalizado',
// metodo: me.refrescarTotalesRegistro,
// directMetodoPhpNombre: 'getRe040102TotalesPorId',
// arrayCamposRefrescar: null, // un array con los nombres de los campos con prefijo incluido, null = todos los recibidos
// arrayCamposNoRefrescar: null // un array con los nombres de los campos con prefijo incluido
// }]
//
// };

subconfig: {
procesosMultiGuardar: [],
procesosPostEditar: []
},

procesosMultiGuardar: [],
procesosPostEditar: [],

//
// Se ejecuta cuando se produce el render de la ficha de edicion
// Es decir justo cuando se ha acabado de cargar y dibujar el control (render)
// Inicializamos valores de campos, mostrar/ocultar campos dinamicamente, etc...
//
onRenderFichaEdicion: function( panelEdicion, eOpts) {
var me = this;

// Procesos que se realizan cuando se acaba de crear/dibujar el control de edicion de la ficha de mantenimiento
if (panelEdicion[me.subconfig.formularioObjNombre]) {
// Mostrar o ocultar campos dinamicos del formulario
if (me['camposDinamicos']) {
me.camposDinamicos( panelEdicion, panelEdicion[me.subconfig.formularioObjNombre] );
}
}

},

//
// Nuevo registro
//
onNuevoAction: function(action, grid, event, eOpts) {
var me = this;

var store = grid.getStore();
var registroRegiso = Ext.create(isoacademiaApp.getModel('registroIso'));
var registro = Ext.create(isoacademiaApp.getModel(me.subconfig.modelNombre));
if (registroRegiso && registro) {
me.editarRegistro('nuevo', registroRegiso, registro, grid);
} else {
Ext.Msg.show({
title: gt.dgettext('isoacademia','Nuevo'),
msg: gt.dgettext('isoacademia','No se puede crear un nuevo registro iso.'),
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
}
},

//
// Editar registro
//
onEditarAction: function(action, grid, event, eOpts) {
var me = this;
var registroRegiso = grid.getSelectionModel().getSelection()[0];
if (registroRegiso) {
me.refrescarEditarRegistro('editar', registroRegiso, grid);
} else {
Ext.Msg.show({
title: gt.dgettext('isoacademia','Editar'),
msg: gt.dgettext('isoacademia','Debe seleccionar un registro iso para editar.'),
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
}
},

//
// Borrar registro
//
onBorrarAction: function(action, grid, event, eOpts) {
var me = this;
var registroRegiso = grid.getSelectionModel().getSelection()[0];
if (registroRegiso) {
me.borrarRegistro(registroRegiso, grid);
} else {
Ext.Msg.show({
title: gt.dgettext('isoacademia','Borrar'),
msg: gt.dgettext('isoacademia','Debe seleccionar un registro iso para borrar.'),
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
}
},

//
// Clonar el registro
//
onClonarAction: function(action, grid, event, eOpts) {
var me = this;
var registroRegiso = grid.getSelectionModel().getSelection()[0];
var mainStatusBar = grid.up('isoacademia_view_main').down('isoacademia_view_mainStatusBar[name="mainStatusBar"]');

if ( !me.subconfig.directMetodoClonarPhpNombre ) {
return false;
}

if ( !window["Ext"]["isoacademiaDirect"][me.subconfig.nombreExtDirect][me.subconfig.directMetodoClonarPhpNombre]) {
Ext.Msg.show({
title: gt.dgettext('isoacademia','Clonar'),
msg: gt.dgettext('isoacademia','Método clonar no definido para este tipo de registro ISO.'),
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
return false;
}

if (registroRegiso) {

// Mostrar mensaje en barra de estado
if (mainStatusBar) {
mainStatusBar.setStatus({
text: gt.dgettext('isoacademia','Clonando registro iso ...'),
iconCls: 'x-status-busy',
clear: false
});
}
// Mostrar mascara
grid.getEl().mask(gt.dgettext('isoacademia','Clonando registro iso ...'));

// Ejecutar accion a traves del proxy direct para clonar / duplicar el RE-XX-XX-XX
//Ext.isoacademiaDirect.isoacademia_re040102.clonarRe040102({
window["Ext"]["isoacademiaDirect"][me.subconfig.nombreExtDirect][me.subconfig.directMetodoClonarPhpNombre]({
regiso_id: registroRegiso.get('regiso_id'),
regiso_guid: registroRegiso.get('regiso_guid'),
regiso_empresa_id: registroRegiso.get('regiso_empresa_id'),
// pasamos fecha para control concurrencia
regiso_fechamod: Ext.Date.format(registroRegiso.get('regiso_fechamod'),'Y-m-d H:i:s')

}, function(provider, response) {

// Limpiar mask pantalla
grid.getEl().unmask();

// Cuando llega la respuesta asincrona, entonces refrescamos el registro original y añadimos el nuevo clonado
if (response.result.success) {
// Comprobar que nos llega el mismo id que hemos pedido
if (response.result.data[0]) {

// Limpiar barra de estado
if (mainStatusBar) {
mainStatusBar.clearStatus({ useDefaults:true, anim: false });
}

if (response.result.data[0].regiso_id==registroRegiso.get('regiso_id')) {
// Pasar todos los datos recibidos al registro original que estaba en el store
registroRegiso.set( response.result.data[0] );
registroRegiso.commit();

// Refrescar el grid para que muestre valores actualizados del registro
grid.getView().refresh();
// Dejamos seleccionado en la lista el registro que acabamos de guardar
grid.getSelectionModel().deselectAll( false );
if ( grid.getStore().findRecord('regiso_id',registroRegiso.get('regiso_id'),0,false,false,true) ) {
grid.getSelectionModel().select([registroRegiso], false, false);
}
}

// Comprobar que nos llega un nuevo id con el registro nuevo clonado
if (response.result.data[1]) {
// Crear registro para guardar los datos "clonados" recibidos (model)
var registroClonado = Ext.create(isoacademiaApp.getModel('registroIso'));
// Pasar todos los datos recibidos al registro que estaba en el store
registroClonado.set( response.result.data[1] );
registroClonado.commit();
// Insertar en la parte superior del grid.
grid.getStore().insert(0,registroClonado);

// Refrescar el grid
grid.getView().refresh();

// Dejamos seleccionado en la lista el registro que nuevo que acabamos de clonar
grid.getSelectionModel().deselectAll( false );
if ( grid.getStore().findRecord('regiso_id',registroClonado.get('regiso_id'),0,false,false,true) ) {
grid.getSelectionModel().select([registroClonado], false, false);
}

// Mostrar mensaje correcto
Ext.Msg.show({
title: gt.dgettext('isoacademia','Clonar registro iso'),
msg: gt.dgettext('isoacademia','Guardado correctamente.'),
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.INFO
});

return true;
}
}
}

// Mostrar mensaje error
if (mainStatusBar) {
mainStatusBar.setStatus({
text: (response.result.message ? response.result.message : gt.dgettext('isoacademia','No se ha podido clonar el registro iso.')),
iconCls: 'x-status-error',
clear: {anim: false, useDefaults: true }
});
}

// Mostrar mensaje que no se puede clonar
Ext.Msg.show({
title: gt.dgettext('isoacademia','Clonar registro iso'),
msg: (response.result.message ? response.result.message : gt.dgettext('isoacademia','No se ha podido clonar el registro iso.<br />Vuelva a refrescar la lista.')),
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.WARNING,
fn: function(btn, text, opt) {
// nada
}
});

return false;
});

} else {
Ext.Msg.show({
title: gt.dgettext('isoacademia','Clonar'),
msg: gt.dgettext('isoacademia','Debe seleccionar un registro iso para clonar.'),
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
}
},

//
// Refrescar un registro ya existente y después Editar el registro
// Ojo se recibe el registro del documento y se refresca obligatoriamente el registro del RE040102 one-to-one
//
refrescarEditarRegistro: function( modo, registroRegiso, grid ) {
var me = this;

if (registroRegiso) {
if (grid) {

// Obligatorio refrescar SIEMPRE !!
// Si lo tenemos configurado en esinube para no hacer los refrescos previos vamos directament a editar.
//if (!esinubeConfig.cfg_av_refrescarRegEditar) {
// // Ahora ya podemos editar el registro
// me.editarRegistro( modo, registroRegiso, registro, grid );
// return true;
//}

// Mostrar "cargando" en barra de estado
var mainStatusBar = grid.up('isoacademia_view_main').down('isoacademia_view_mainStatusBar[name="mainStatusBar"]');
if (mainStatusBar) {
mainStatusBar.setStatus({
text: gt.dgettext('isoacademia','Cargando registro para editar ... ') + registroRegiso.get('regiso_id'),
iconCls: 'x-status-busy',
clear: false
});
}

// Ejecutar funcion extdirect para refrescar el registro que corresponde al id solicitado para editar
// Asi cogemos los datos mas recientes para editar
//Ext.isoacademiaDirect.isoacademia_re040102.getRe040102({
window["Ext"]["isoacademiaDirect"][me.subconfig.nombreExtDirect]["get" + me.subconfig.nombreMayusPlural]({
filter: [{
property: me.subconfig.modelPrefijoCampos + 'regiso_id',
value: registroRegiso.get('regiso_id')
}]

}, function(provider, response) {

// Cuando llega la respuesta asincrona, entonces editamos el registro si ha ido bien la carga del refresco
if (response.result.success) {
// Comprobar que nos llega el mismo id que hemos pedido
if (response.result.data[0]) {

// Limpiar barra de estado
if (mainStatusBar) {
mainStatusBar.clearStatus({ useDefaults:true, anim: false });
}

if (response.result.data[0][me.subconfig.modelPrefijoCampos + 'regiso_id'] == registroRegiso.get('regiso_id')) {
// Pasar los datos recibidos al registro del documento que estaba en el store
// Asignará solo los campos que estan en el modelo del documento regiso_xxxxx
registroRegiso.set( response.result.data[0] );
registroRegiso.commit();

// Ahora creamos un registro del modelo RExxxxxx concreto (p.ex. model.re040102)
// para poder editar y le cargamos los datos recibidos
var registro = Ext.create(isoacademiaApp.getModel(me.subconfig.modelNombre));
registro.set( response.result.data[0] );
registro.commit();

// Ahora ya podemos editar el registro
me.editarRegistro( modo, registroRegiso, registro, grid );
return true;
}
}
}

// Mostrar mensaje error
if (mainStatusBar) {
mainStatusBar.setStatus({
text: gt.dgettext('isoacademia','No se ha podido cargar/refrescar el registro antes de editar.'),
iconCls: 'x-status-error',
clear: {anim: false, useDefaults: true }
});
}

// Mostrar mensaje que no se puede editar el registro
Ext.Msg.show({
title: gt.dgettext('isoacademia','Editar'),
msg: gt.dgettext('isoacademia','No se ha podido cargar/refrescar el registro antes de editar.<br />Inténtelo dentro de unos segundos o vuelva a refrescar la lista.'),
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.WARNING,
fn: function(btn, text, opt) {
// nada
}
})
return false;
}
);
}
}
},

//
// Editar un registro
//
editarRegistro: function( modo, registroRegiso, registro, grid ) {
var me = this;

if (registroRegiso && registro) {
if (grid) {
var tabpanel = grid.up('isoacademia_view_registrosIso_mant'); // Se usa el grid i mant de DOCUMENTOS
if (tabpanel) {
// Crear la vista de edicion (formulario de edicion)
//var mantEdicion = isoacademiaApp.getView('re040102.mantEdicion');
var mantEdicion = isoacademiaApp.getView(me.subconfig.viewMantEdicion);
if (mantEdicion) {
// Comprobar si ya está abierta esta ficha por su idAsociado y simplemente mostrar
//var fichasAbiertas = tabpanel.query('isoacademia_view_re040102_mantEdicion[name="edicionRe040102_id_'+registro.get('re040102_id').toString()+'"]');
var fichasAbiertas = tabpanel.query('isoacademia_view_' + me.subconfig.viewMantEdicionAlias + '[name="edicion' + me.subconfig.nombreMayus +'_id_'+registro.get(me.subconfig.modelPrefijoCampos + 'id').toString()+'"]');
if (modo!='nuevo' && fichasAbiertas.length > 0) {
// Mostrar la ficha ya abierta anteriormente
tabpanel.setActiveTab(fichasAbiertas[0]);
} else {
// Crear la vista de la ficha para editar
var mantEdicionView = mantEdicion.create({
name: 'edicion' + me.subconfig.nombreMayus +'_id_' + registro.get(me.subconfig.modelPrefijoCampos + 'id').toString(),
modo: modo,
registroRegisoAsociado: registroRegiso,
registroAsociado: registro,
gridAsociado: grid
});
// Abrir opcion en un nuevo tab
tabpanel.add( mantEdicionView );
tabpanel.setActiveTab( mantEdicionView );
}
}
}
}
}
},

//
// Borrar un registro
// No usamos el método destroy del data.model porque tenemos que enviar un model del rexxxxxx, y el que tenemos en el
// grid es del tipo registroIso. Lo hacemos llamando al extdirect con el metodo destroy directamente, como en el
// proceso de clonar.
//
borrarRegistro: function( registroRegiso, grid ) {
var me = this;

if (registroRegiso) {

if ( !window["Ext"]["isoacademiaDirect"][me.subconfig.nombreExtDirect]["destroy" + me.subconfig.nombreMayus]) {
Ext.Msg.show({
title: gt.dgettext('isoacademia','Borrar'),
msg: gt.dgettext('isoacademia','Método destroy no definido para este tipo de registro ISO.'),
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
return false;
}

mensajeConf = gt.dgettext('isoacademia','Seguro que desea borrar el registro iso ?') + '<br />' + (me.subconfig.confBorrarMostrarCampo ? registroRegiso.get(me.subconfig.confBorrarMostrarCampo) : ''),

// Pedir conformidad para borrar
Ext.Msg.show({
title: gt.dgettext('isoacademia','Borrar'),
msg: mensajeConf,
buttons: Ext.Msg.YESNO,
//icon: Ext.MessageBox.QUESTION,
icon: Ext.MessageBox.WARNING,
fn: function(btn, text, opt) {
if (btn == 'yes') {

// Mostrar "borrando" en barra de estado
var mainStatusBar = grid.up('isoacademia_view_main').down('isoacademia_view_mainStatusBar[name="mainStatusBar"]');
if (mainStatusBar) {
mainStatusBar.setStatus({
text: gt.dgettext('isoacademia','Borrando registro ...') + ' ' + (me.subconfig.confBorrarMostrarCampo ? registroRegiso.get(me.subconfig.confBorrarMostrarCampo) : ''),
iconCls: 'x-status-busy',
clear: false
});
}
// Mostrar mascara
grid.getEl().mask(gt.dgettext('isoacademia','Borrando registro ...'));


// Ejecutar accion a traves del proxy direct para BORRAR el RE-XX-XX-XX
//Ext.isoacademiaDirect.isoacademia_re040102.destroyRe040102({
window["Ext"]["isoacademiaDirect"][me.subconfig.nombreExtDirect]["destroy" + me.subconfig.nombreMayus]({
regiso_id: registroRegiso.get('regiso_id'),
regiso_guid: registroRegiso.get('regiso_guid'),
regiso_empresa_id: registroRegiso.get('regiso_empresa_id'),
// pasamos fecha para control concurrencia
regiso_fechamod: Ext.Date.format(registroRegiso.get('regiso_fechamod'),'Y-m-d H:i:s')

}, function(provider, response) {

// Limpiar mask pantalla
grid.getEl().unmask();

// Cuando llega la respuesta asincrona, entonces refrescamos el registro original y añadimos el nuevo clonado
if (response.result.success) {

// Limpiar barra de estado
if (mainStatusBar) {
mainStatusBar.clearStatus({ useDefaults:true, anim: false });
}

// Borrar correcto. Quitar el registro Iso del store
grid.getStore().remove( registroRegiso );
// Forzar cambios hechos en el store para que no lanze operaciones con el registro borrado
grid.getStore().commitChanges();

return true;
}

// Mostrar mensaje error
if (mainStatusBar) {
mainStatusBar.setStatus({
text: (response.result.message ? response.result.message : gt.dgettext('isoacademia','No se ha podido borrar el registro iso.')),
iconCls: 'x-status-error',
clear: {anim: false, useDefaults: true }
});
}

// Mostrar mensaje que no se puede borrar
Ext.Msg.show({
title: gt.dgettext('isoacademia','Borrar registro iso'),
msg: (response.result.message ? response.result.message : gt.dgettext('isoacademia','No se ha podido borrar el registro iso.')),
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.WARNING,
fn: function(btn, text, opt) {
// nada
}
});

return false;
});
}
}
})
}
},

//
// Cancelar y volver
//
onCancelarAction: function(action, panelEdicion, event, eOpts) {
var me = this;
//var formulario = panelEdicion.formularioRe040102;
var formulario = panelEdicion[me.subconfig.formularioObjNombre];
var registroRegiso = panelEdicion.registroRegisoAsociado;
var registro = formulario.getRecord()
var grid = panelEdicion.up('isoacademia_view_registrosIso_mant').down('isoacademia_view_registrosIso_mantGrid[name="gridRegistrosIso"]');

if (panelEdicion.modo=="nuevo") {
// Eliminar registro creado porque aun no se ha agregado al store
registroRegiso = null;
registro = null;
} else if (panelEdicion.modo=="editar") {
// Volver a poner los campos modificados tal como estaban al principio
registroRegiso.set( registroRegiso.modified );
// Forzar cambios hechos en el store para que no lanze operaciones con el registro tocado
panelEdicion.storeAsociado.commitChanges();
}
if (panelEdicion.modo=='nuevo') {
// Cerrar el panel de edicion de este registro
Ext.destroy(panelEdicion);
} else {
// Lanzar los procesos posteditar (refrescar totales, etc...) pero sin pasar por "multiguardar"
me.postEditar(registroRegiso, registro, panelEdicion);
// El postEditar es la última parte de la edición y ya hace el destroy del panelEdicion
if (panelEdicion.modo=="editar") {
registro = null;
}
}
},

//
// Guardar registro
//
onGuardarAction: function(action, panelEdicion, event, eOpts) {
var me = this;
//var formulario = panelEdicion.formularioRe040102;
var formulario = panelEdicion[me.subconfig.formularioObjNombre];
var formBasic = formulario.getForm();
var registroRegiso = panelEdicion.registroRegisoAsociado;
var registro = formulario.getRecord();
var mainStatusBar = panelEdicion.up('isoacademia_view_main').down('isoacademia_view_mainStatusBar[name="mainStatusBar"]');
var grid = panelEdicion.up('isoacademia_view_registrosIso_mant').down('isoacademia_view_registrosIso_mantGrid[name="gridRegistrosIso"]');

if (formulario && panelEdicion.storeAsociado) {

// Validar campos escoge, windows escoge, campos formulario principal, formularios anidados, etc...
// antes de proceder a guardar
if (!me.validarPreGuardar( panelEdicion, grid, formulario, registroRegiso, registro )) {
return false;
}

// Cargar valores del formulario en el registro asociado
registro.set( formulario.getValues() );

// asignar el proxy direct del store que corresponde al registro
//registro.setProxy(panelEdicion.storeAsociado.getProxy());
registro.setProxy(isoacademiaApp.getStore(me.subconfig.storeNombre).getProxy());

// Mostrar "guardando" en barra de estado
if (mainStatusBar) {
mainStatusBar.setStatus({
text: gt.dgettext('isoacademia','Guardando registro ... ') + registro.get(me.subconfig.modelPrefijoCampos + 'id'),
iconCls: 'x-status-busy',
clear: false
});
}
// Mostrar mascara
panelEdicion.getEl().mask(gt.dgettext('isoacademia','Guardando...'));

// Iniciar tabla de configuraciones del proceso multiguardar
// Asi se pueden ejecutar los procesos de guardar asincronos de forma consecutiva si van bien
// y al final cerrar el formulario de edicion o dejarlo si hay errores en cualquier guardar.
me.procesosMultiGuardar = me.subconfig.procesosMultiGuardar;

// Guardar registro a traves del proxy direct
registro.save({
// Procesar respuesta
callback: function( records, operation) {
panelEdicion.getEl().unmask();

if (operation.wasSuccessful()) {
// Limpiar barra de estado
if (mainStatusBar) {
mainStatusBar.clearStatus({ useDefaults:true, anim: false });
}
//console.log(operation.response);
//console.log(operation.response.result);
// Guardar correcto
if ( panelEdicion.modo=="nuevo" ) {
// OJO el storeAsociado es el de la tabla RegistrosIso
// Asignamos los valores recibidos despues de guardar al registro del registro-iso
// solo se actualizaran los campos regiso_xxxx
registroRegiso.set( registro.getData() );
// Agregar el registro al store si se ha guardado bien y no existe ya.
if ( panelEdicion.storeAsociado.findExact(me.subconfig.modelPrefijoCampos + 'id',registroRegiso.get(me.subconfig.modelPrefijoCampos + 'id')) == -1) {
panelEdicion.storeAsociado.insert(0,registroRegiso);
//panelEdicion.storeAsociado.add(registro);
}
// Forzar cambios hechos en el store para que no lanze operaciones con el registro agregado
panelEdicion.storeAsociado.commitChanges();
} else {
// Si estamos modificando tambien hay que sobreescribir los valores del registroRegiso
// Asignamos los valores recibidos despues de guardar al registro del registro-iso
// solo se actualizaran los campos regiso_xxxx, o alguno adjunto re040102_ si existe definido en el modelo del doc
registroRegiso.set( registro.getData() );
// Forzar cambios hechos en el store para que no lanze operaciones con el registro modificado
panelEdicion.storeAsociado.commitChanges();
}

// Informar que hemos completado correctamente la tarea de guardar ficha para el multiguardar
me.completarMultiGuardar(-1, registroRegiso, registro, panelEdicion, true);

} else {
// Error al guardar
if (operation.hasException()) {
var mensajeError = operation.getError();
var iconoError = Ext.Msg.WARNING
} else {
var mensajeError = gt.dgettext('isoacademia','Error: No se han podido guardar los datos.');
var iconoError = Ext.Msg.ERROR
}

// Mostrar mensaje error
if (mainStatusBar) {
mainStatusBar.setStatus({
text: mensajeError,
iconCls: 'x-status-error',
//clear: true
clear: { useDefaults:true, anim: false }
});
}

Ext.Msg.show({
title: gt.dgettext('isoacademia','Guardar'),
msg: mensajeError,
buttons: Ext.Msg.OK,
icon: iconoError
});

// Informar que hemos completado con errores la tarea de guardar ficha para el multiguardar
me.completarMultiGuardar(-1, registroRegiso, registro, panelEdicion, false);
}
}
});
}
},


//
// Condiciones a comprobar antes de guardar
//
validarPreGuardar: function(panelEdicion, grid, formulario, registroRegiso, registroFicha ) {
var me = this;

// Con ventanas escoge abiertas no se puede guardar
var arrayCamposEscogeNombre = me.subconfig.preGuardar.arrayCamposEscogeNombre;
var campoEscoge;
if (arrayCamposEscogeNombre) {
for (var ceIndex=0; ceIndex<arrayCamposEscogeNombre.length; ceIndex++) {
campoEscoge = formulario.getForm().findField(arrayCamposEscogeNombre[ceIndex]);
if (campoEscoge) {
if ( campoEscoge.isDirty() ) {
campoEscoge.markInvalid( gt.dgettext('isoacademia','Debe introducir o seleccionar un valor válido.') );
return false;
}
}
}
}

// Con ventanas escoge abiertas no se puede guardar
var arrayVentanasEscoge = me.subconfig.preGuardar.arrayVentanasEscoge;
var ventanaEscoge;
if (arrayVentanasEscoge) {
for (var veIndex=0; veIndex<arrayVentanasEscoge.length; veIndex++) {
ventanaEscoge = grid[arrayVentanasEscoge[veIndex]];
if (ventanaEscoge) {
if ( ventanaEscoge.isVisible() ) {
Ext.Msg.show({
title: gt.dgettext('isoacademia','Guardar'),
msg: gt.dgettext('isoacademia','Tiene ventanas de selección abiertas. No puede guardar.'),
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
return false;
}
}
}
}

// Antes de guardar comprobar que no existen formularios anidados (da problemas porque getValues devuelve todos los anidados)
var arrayViewMantSubfichas = me.subconfig.preGuardar.arrayViewMantSubfichas;
var formAnidado;
if (arrayViewMantSubfichas) {
for (var faIndex=0; faIndex<arrayViewMantSubfichas.length; faIndex++) {
formAnidado = panelEdicion.down('isoacademia_view_' + arrayViewMantSubfichas[faIndex]);
if (formAnidado) {
Ext.Msg.show({
title: gt.dgettext('isoacademia','Guardar'),
msg: gt.dgettext('isoacademia','Está editando subfichas del registro iso. Acepte o cancele la edición de las subfichas que tiene abiertas, antes de guardar el registro iso.'),
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
return false;
}
}
}

// Revisar campos del formulario: obligatorios, etc...)
if (!formulario.getForm().isValid()) {
var camposFormulario = formulario.getForm().getFields();
var cadenaLabelsRevisar = '';
camposFormulario.each(function(campo, index, len) {
if (!campo.validate()) {
var etiqueta = '';
etiqueta = etiqueta + (campo.up('isoacademia_view_panelSubfichaBase',2) ? ' (' + gt.dgettext('isoacademia_view_panelSubfichaBase','Pestaña:') + ' ' + campo.up('isoacademia_view_panelSubfichaBase',2).title +') ' : '');
etiqueta = etiqueta + (campo.up('fieldcontainer',1) ? ' ' + campo.up('fieldcontainer',1).fieldLabel : '');
if (campo.fieldLabel) {
etiqueta = etiqueta + (Ext.String.trim(etiqueta).length>0 ? ' - ' : ' ') + (campo.fieldLabel ? campo.fieldLabel : '');
}
cadenaLabelsRevisar = cadenaLabelsRevisar + (cadenaLabelsRevisar.length>0 ? ', ' : '') + etiqueta;
}
});
Ext.Msg.show({
title: gt.dgettext('isoacademia','Guardar'),
msg: gt.dgettext('isoacademia','Revise los siguientes campos: ')+cadenaLabelsRevisar,
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
return false;
}

return true;
},

//
// Completar cada fase del multiguardar y lanzar la siguiente
//
completarMultiGuardar: function(multiguardarIndex, registroRegiso, registroFicha, panelEdicion, success) {
var me = this;
var grid = panelEdicion.up('isoacademia_view_registrosIso_mant').down('isoacademia_view_registrosIso_mantGrid[name="gridRegistrosIso"]');
var siguienteProcesoIndex = null;
var siguienteProcesoConfig = null;

// if (multiguardarIndex == (-1) ) {
// el menos uno se usa para completar el guardar principal de la ficha, que no se incluye en el array multiguardar
// porque se debe hacer siempre
//}

if (success) {
siguienteProcesoIndex = multiguardarIndex + 1
// comprobar si hay más procesos que completar. Si el index completado esta en el rango de elementos de los procesosMultiGuardar
if (siguienteProcesoIndex < me.procesosMultiGuardar.length) {
siguienteProcesoConfig = me.procesosMultiGuardar[siguienteProcesoIndex];

switch (siguienteProcesoConfig.tipo) {
// sincronizar una tabla de subfichas
case 'subfichasSync':
me.syncSubfichas(siguienteProcesoIndex, siguienteProcesoConfig, registroRegiso, registroFicha, panelEdicion);
break;
// ejecutar un método personalizado
case 'personalizado':
if (Ext.isFunction(siguienteProcesoConfig.metodo)) {
// Llamar al método en el scope (this / me) añadiendo .bind(scope) al final
siguienteProcesoConfig.metodo.bind(me)(siguienteProcesoIndex, siguienteProcesoConfig, registroRegiso, registroFicha, panelEdicion);
}
break;
}

} else {
// Ya no hay mas procesos que completar
// Lanzar los procesos posteditar
me.postEditar(registroRegiso, registroFicha, panelEdicion);
}
}
},

//
// Lanzar los procesos del post-editar
//
postEditar: function(registroRegiso, registroFicha, panelEdicion) {
var me = this;

// Iniciar tabla de configuraciones del proceso posteditar
me.procesosPostEditar = me.subconfig.procesosPostEditar;

// Lanzar el primer proceso del post editar, i si no hay ninguno se cerrará la edición
me.completarPostEditar(-1, registroRegiso, registroFicha, panelEdicion, true);
},

//
// Completar cada fase del post-editar y lanzar la siguiente
//
completarPostEditar: function(posteditarIndex, registroRegiso, registroFicha, panelEdicion, success) {
var me = this;
var grid = panelEdicion.up('isoacademia_view_registrosIso_mant').down('isoacademia_view_registrosIso_mantGrid[name="gridRegistrosIso"]');
var siguienteProcesoIndex = null;
var siguienteProcesoConfig = null;

// if (posteditarIndex == (-1) ) {
// el menos uno se usa para lanzar el primer proceso
//}

if (success) {
siguienteProcesoIndex = posteditarIndex + 1
// comprobar si hay más procesos que completar. Si el index completado esta en el rango de elementos de los procesosPostEditar
if (siguienteProcesoIndex < me.procesosPostEditar.length) {
siguienteProcesoConfig = me.procesosPostEditar[siguienteProcesoIndex];

switch (siguienteProcesoConfig.tipo) {
// ejecutar un método personalizado
case 'personalizado':
if (Ext.isFunction(siguienteProcesoConfig.metodo)) {
// Llamar al método en el scope (this / me) añadiendo .bind(scope) al final
siguienteProcesoConfig.metodo.bind(me)(siguienteProcesoIndex, siguienteProcesoConfig, registroRegiso, registroFicha, panelEdicion);
}
break;
}

} else {
// Ya no hay mas procesos que completar

// Cerrar el panel de edicion
Ext.destroy(panelEdicion);
// Refrescar el grid para que muestre valores actualizados del registro
grid.getView().refresh();
// Dejamos seleccionado en la lista el registro que acabamos de guardar
grid.getSelectionModel().deselectAll( false );
if ( grid.getStore().findRecord('regiso_id',registroRegiso.get('regiso_id'),0,false,false,true) ) {
grid.getSelectionModel().select([registroRegiso], false, false);
}
}
}
},

//
// Sincronizar subfichas (hace los destroy, create, update) de forma asincrona.
//
// Ejemplo config: {
// tipo: 'subfichasSync',
// nombre: 're040102Lin',
// descripcionMinus: gt.dgettext('isoacademia','línea'),
// descripcionMinusPlural: gt.dgettext('isoacademia','líneas'),
// descripcionMayus: gt.dgettext('isoacademia','Línea'),
// descripcionMayusPlural: gt.dgettext('isoacademia','Líneas'),
// viewGridNombre: 're040102Lin.mantGrid',
// viewGridAlias: 're040102Lin_mantGrid',
// modelNombre: 're040102lin',
// modelPrefijoCampos: 're040102lin_',
// modelCampoEnlace: 're040102lin_recab_id'
// }
syncSubfichas: function(multiguardarIndex, config, registroRegiso, registroFicha, panelEdicion) {
var me = this;
var ficha_id = registroFicha.get(me.subconfig.modelPrefijoCampos + 'id');
var gridSubfichas = panelEdicion.down('isoacademia_view_' + config.viewGridAlias);
var storeSubfichas = gridSubfichas.getStore();
var mainStatusBar = panelEdicion.up('isoacademia_view_main').down('isoacademia_view_mainStatusBar[name="mainStatusBar"]');

// Comprobar si hay registros que actualizar
if ( !(storeSubfichas.getModifiedRecords().length>0 || storeSubfichas.getRemovedRecords().length>0) ) {
// Informar que hemos completado correctamente la tarea de guardar las subfichas para el multiguardar
me.completarMultiGuardar(multiguardarIndex, registroRegiso, registroFicha, panelEdicion, true);
return true;
}

// Si la subficha era nueva y aun no se habia guardado por primera vez hay que poner el ficha_id en los campos de enlace
if ( panelEdicion.modo=="nuevo" ) {
var regsModificadosoNuevos = storeSubfichas.getModifiedRecords();
for (var i=0; i<regsModificadosoNuevos.length; i++) {
regsModificadosoNuevos[i].set(config.modelCampoEnlace,ficha_id);
}
var regsBorrados = storeSubfichas.getRemovedRecords(); // No haria falta ponerlo en los borrados.
for (var i=0; i<regsBorrados.length; i++) {
regsBorrados[i].set(config.modelCampoEnlace,ficha_id);
}
}

// Mostrar "guardando" en barra de estado
if (mainStatusBar) {
mainStatusBar.setStatus({
text: gt.dgettext('isoacademia','Guardando registro ... ') + ' ' + config.descripcionMayusPlural + ' ...',
iconCls: 'x-status-busy',
clear: false
});
}
// Mostrar mascara
panelEdicion.getEl().mask(gt.dgettext('isoacademia','Guardando') + ' ' + config.descripcionMinusPlural + ' ...');


// Ejecutar el sync del store (lanza en modo batch todos los destroy, create y update a través del proxy de forma asincrona)
storeSubfichas.sync({

// operaciones crud todas correctas
success: function(batch, options) {
// Limpiar barra de estado
if (mainStatusBar) {
mainStatusBar.clearStatus({ useDefaults:true, anim: false });
}
panelEdicion.getEl().unmask();
// Informar que hemos completado correctamente la tarea de guardar las subfichas para el multiguardar
me.completarMultiGuardar(multiguardarIndex, registroRegiso, registroFicha, panelEdicion, true);
},

// Alguna operacion crud con fallos
failure: function(batch, options) {
// Limpiar barra de estado
if (mainStatusBar) {
mainStatusBar.clearStatus({ useDefaults:true, anim: false });
}
panelEdicion.getEl().unmask();

// Cadena con el mensaje de error a mostrar
var mensajeError = null;

// Recorrer resultados de las operaciones crud generadas automaticamente por sync()
for (var i=0; i<batch.operations.length; i++) {
var operacion = batch.operations[i];
// Error en la operacion (solo puede ser create, update o destroy)
if (operacion.hasException()) {
// Obtener registros que han generado la operacion.
var registrosOperacion = operacion.getRecords();
// Si solo se mandó un registro el único error posible no viene en un array sino en un string directo
if (registrosOperacion.length==1 || (typeof operacion.getError())=="string") {
var registroOperacion = registrosOperacion[0];
if (registroOperacion) {
// Si la accion era borrar y ha fallado volver a poner el registro borrado en el store
if (operacion.action=='destroy') {
storeSubfichas.add(registroOperacion);
}
// Montar cadena mensaje de error
mensajeError = (mensajeError==null ? '' : mensajeError + '<br />') + config.descripcionMayus + ': ' + registroOperacion.get(config.modelPrefijoCampos + 'id') + '<br />' + operacion.getError();
}

} else {

// Si se mandaron multiples registros aunque solo haya un error viene en un array con 2 partes
// php $respuesta['message']['errores'] array de mensajes de error
// php $respuesta['message']['data'] registros refrescados despues de procesar o con el valor original si han fallado
// obtener array de mensajes de error si los hay (en sync batch mode sera un array con estas keys 'indexRegOpe', 'errorNum' , 'errorMsg', 'message'
var mensajesErrorOperacion = operacion.getError().errores;

// Montar cadena error y recuperar borrados que han fallado
if (mensajesErrorOperacion==null || mensajesErrorOperacion.length<=0) {
mensajeError = (mensajeError==null ? '' : mensajeError + '<br />') + gt.dgettext('isoacademia','Error al guardar') + ' ' + config.descripcionMinusPlural +'. ('+operacion.action+')';
} else {
// Bucle para montar el mensaje de error
for (var j=0; j<mensajesErrorOperacion.length; j++) {
if (typeof mensajesErrorOperacion[j]['indexRegOpe'] != "undefined") {
if ( mensajesErrorOperacion[j]['indexRegOpe']>=0 && mensajesErrorOperacion[j]['indexRegOpe']<registrosOperacion.length) {
// Coger el registro original que corresponde al error recibido
var registroOperacion = registrosOperacion[ mensajesErrorOperacion[j]['indexRegOpe'] ];
if (registroOperacion) {
// Si la accion era borrar y ha fallado volver a poner el registro borrado en el store
if (operacion.action=='destroy') {
storeSubfichas.add(registroOperacion);
}
// Montar cadena mensaje de error
mensajeError = (mensajeError==null ? '' : mensajeError + '<br />') + config.descripcionMayus + ': ' + registroOperacion.get(config.modelPrefijoCampos + 'id') + '<br />' + mensajesErrorOperacion[j]['message'];
}
}
}
}
}


// Aunque haya errores actualizamos los otros registros en create y update
// que si hayan ido bien y han devuelto el data refrescado
// php $respuesta['message']['data'] registros refrescados despues de procesar o con el valor original si han fallado
var dataRespuestaOperacion = operacion.getError().data;
if (dataRespuestaOperacion) {
var registrosRespuestaOperacion = storeSubfichas.getProxy().getReader().read(dataRespuestaOperacion).records;
if ((operacion.action=='create' || operacion.action=='update') && registrosRespuestaOperacion) {
// Recorremos todos los registros originales enviados en la operacion para ver si se pueden actualizar
// con su homonimo recibido del php
for (var r=0; r<registrosOperacion.length; r++) {
// Mirar si el index r no esta entre los registros que tiene error
var regConError = false;
for (var j=0; j<mensajesErrorOperacion.length; j++) {
if ( mensajesErrorOperacion[j]['indexRegOpe']==r) {
regConError = true;
break;
}
}
if (!regConError) {
var registroOperacion = registrosOperacion[r];
var registroRespuestaOperacion = registrosRespuestaOperacion[r];
if (registroOperacion && registroRespuestaOperacion) {
// Si el registro original no es nuevo (phantom), asegurarse que los ids coinciden entre el registro original enviado y el recibido.
if(registroOperacion.getId() === registroRespuestaOperacion.getId() || registroOperacion.phantom ) {
registroOperacion.copyFrom(registroRespuestaOperacion);
registroOperacion.commit();
}
}
}
}
}
} // Fin commits

} // Fin varios registros
} // Fin tiene algun error operacion
} // Fin bucle operaciones


// Se muestra un solo mensaje de error con los textos de todas las operaciones
if (mensajeError) {
Ext.Msg.show({
title: config.descripcionMayusPlural,
msg: mensajeError,
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
}

// Puesto que si falla algun borrar se reagrega el registro al store, limpiamos el array de borrados para el siguiente sync.
storeSubfichas.removed = [];

// Informar que hemos completado con errores la tarea de guardar las subfichas para el multiguardar
me.completarMultiGuardar(multiguardarIndex, registroRegiso, registroFicha, panelEdicion, false);
}
});

},

//
// Refrescar totales de un registro ya existente o acabado de guardar
//
refrescarTotalesRegistro: function(posteditarIndex, config, registroRegiso, registroFicha, panelEdicion ) {
var me = this;
var grid = panelEdicion.up('isoacademia_view_registrosIso_mant').down('isoacademia_view_registrosIso_mantGrid[name="gridRegistrosIso"]');

if (registroRegiso && registroFicha) {

// Mostrar "refrescando" en barra de estado
var mainStatusBar = grid.up('isoacademia_view_main').down('isoacademia_view_mainStatusBar[name="mainStatusBar"]');
if (mainStatusBar) {
mainStatusBar.setStatus({
text: gt.dgettext('isoacademia','Refrescando totales del registro ... ') + registroFicha.get(me.subconfig.modelPrefijoCampos + 'id'),
iconCls: 'x-status-busy',
clear: false
});
}
// Mostrar mascara
panelEdicion.getEl().mask(gt.dgettext('isoacademia','Refrescando totales del registro ...'));

// Ejecutar funcion extdirect para refrescar el registroFicha que corresponde al id solicitado para editar
// Asi cogemos los datos mas recientes para editar
// Parámetros que enviamos id, guid, empresa_id
// Hay que crearlo así para poder poner los nombres con los prefijos configurables
var parametrosRefrescarDirect = {}
parametrosRefrescarDirect[me.subconfig.modelPrefijoCampos + 'id'] = registroFicha.get(me.subconfig.modelPrefijoCampos + 'id');
parametrosRefrescarDirect[me.subconfig.modelPrefijoCampos + 'guid'] = registroFicha.get(me.subconfig.modelPrefijoCampos + 'guid');
if ( registroFicha.fields.indexOfKey(me.subconfig.modelPrefijoCampos + 'empresa_id') != (-1) ) {
parametrosRefrescarDirect[me.subconfig.modelPrefijoCampos + 'empresa_id'] = registroFicha.get(me.subconfig.modelPrefijoCampos + 'empresa_id');
}

//Ext.isoacademiaDirect.isoacademia_rexxxxxx.getRexxxxxxTotalesPorId({
window["Ext"]["isoacademiaDirect"][me.subconfig.nombreExtDirect][config.directMetodoPhpNombre](

// pasamos los parametros
parametrosRefrescarDirect

, function(provider, response) {

panelEdicion.getEl().unmask();

// Cuando llega la respuesta asincrona, entonces editamos el registroFicha si ha ido bien la carga del refresco
if (response.result.success) {
// Comprobar que nos llega el mismo id que hemos pedido
if (response.result.data[0]) {

// Limpiar barra de estado
if (mainStatusBar) {
mainStatusBar.clearStatus({ useDefaults:true, anim: false });
}

if (response.result.data[0][me.subconfig.modelPrefijoCampos + 'id']==registroFicha.get(me.subconfig.modelPrefijoCampos + 'id')) {
// Pasar los datos de los totales recibidos al registroFicha que estaba en el store
var arrayCamposRefrescar = config.arrayCamposRefrescar;
var arrayCamposNoRefrescar = config.arrayCamposNoRefrescar;

// Refrescar solo algunos campos recibidos por el Ext.Direct
if ((arrayCamposRefrescar && arrayCamposRefrescar.length>0) || (arrayCamposNoRefrescar && arrayCamposNoRefrescar.length>0)) {
for( var campoRecibidoNombre in response.result.data[0] ) {
// Mirar si es un campo a refrescar
if (arrayCamposRefrescar.length==0 || arrayCamposRefrescar.indexOf(campoRecibidoNombre) != (-1)) {
// Mirar si es un campo a NO refrescar
if (arrayCamposNoRefrescar.length==0 || arrayCamposNoRefrescar.indexOf(campoRecibidoNombre) == (-1)) {
// Refrescar
registroFicha.set( campoRecibidoNombre, response.result.data[0][campoRecibidoNombre] );
}
}
}
} else {
// Refrescar todos los campos recibidos por el Ext.Direct
registroFicha.set( response.result.data[0] );
}
registroFicha.commit();

// Informar que hemos completado correctamente la tarea refrescar los totales para el posteditar
me.completarPostEditar(posteditarIndex, registroRegiso, registroFicha, panelEdicion, true);
return true;
}
}
}

// Mostrar mensaje error
if (mainStatusBar) {
mainStatusBar.setStatus({
text: gt.dgettext('isoacademia','No se han podido refrescar los totales del registro.'),
iconCls: 'x-status-error',
clear: {anim: false, useDefaults: true }
});
}

// Mostrar mensaje que no se puede editar el registro
Ext.Msg.show({
title: gt.dgettext('isoacademia','Editar'),
msg: gt.dgettext('isoacademia','No se han podido refrescar los totales del registro.<br />Vuelva a refrescar la lista.'),
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.WARNING,
fn: function(btn, text, opt) {
// nada
}
})

// Informar que hemos completado con errores la tarea refrescar los totales para el posteditar
me.completarPostEditar(posteditarIndex, registroRegiso, registroFicha, panelEdicion, false);
return false;
}
);
}
}


// Se definen en cada controller extendido
// //
// // Función para forzar o no forzar los campos como obligatorios
// //
// camposDinamicos: function( panelEdicion, formulario ) {
// //var me = this;
// //var formBasic = formulario.getForm();
// //var ctrlCamposDinamicos = isoacademiaApp.getController('camposDinamicos');
//
// //Ext.suspendLayouts();
// //Ext.resumeLayouts(true);
// }

});


First controller with base functionality:



//@charset UTF-8

Ext.define('isoacademia.controller.re040102.mant', {
extend: 'Ext.app.Controller',

// Añadir las propiedades y metodos del del patron rexxxxxx.mant a esta clase
// Ojo los métodos que estan definidos en esta clase , si existen en el patron, no se copian.
mixins:[
'isoacademia.controller.rexxxxxx.mant'
],

models:[
're040102'
],
stores:[
're040102'
],
views: [
're040102.mantEdicion'
],

init: function() {
var me = this;

// Ejecutar método del parent
this.callParent(arguments);

me.control({
'isoacademia_view_re040102_mantEdicion' : {
afterrender: me.onRenderFichaEdicion,
guardar: me.onGuardarAction,
cancelar: me.onCancelarAction
}
});

},

// Definir los nombres, configuraciones y otros valores del sub-controller
subconfig: {
nombreMinus: 're040102',
nombreMinusPlural: 're040102',
nombreMayus: 'Re040102',
nombreMayusPlural: 'Re040102',

nombreExtDirect: 'isoacademia_re040102',
directMetodoClonarPhpNombre: 'clonarRe040102',

modelNombre: 're040102',
modelPrefijoCampos: 're040102_',
storeNombre: 're040102',

viewMantEdicion: 're040102.mantEdicion',
viewMantEdicionAlias: 're040102_mantEdicion',
formularioObjNombre: 'formularioRe040102',

// Nombre del campo que se muestra al pedir confirmación para borrar
confBorrarMostrarCampo: 'regiso_id',

// validaciones para el pre-guardar
preGuardar: {
arrayCamposEscogeNombre: [], // Nombres de los campos que corresponden a un "escoge" en el formulario principal
arrayVentanasEscoge: [], // Ventanas escoge definidas en el grid principal
arrayViewMantSubfichas: ['re040102Lin_mantEdicion'] // Alias de los mantenimientos de las subfichas anidadas a la ficha principal
},

// Procesos que se ejecutan conscutivamente después de guardar (save) la ficha principal
procesosMultiGuardar: [{
nombre: 're040102Lin',
tipo: 'subfichasSync',
descripcionMinus: gt.dgettext('isoacademia','línea'),
descripcionMinusPlural: gt.dgettext('isoacademia','líneas'),
descripcionMayus: gt.dgettext('isoacademia','Línea'),
descripcionMayusPlural: gt.dgettext('isoacademia','Líneas'),
viewGridNombre: 're040102Lin.mantGrid',
viewGridAlias: 're040102Lin_mantGrid',
modelNombre: 're040102lin',
modelPrefijoCampos: 're040102lin_',
modelCampoEnlace: 're040102lin_recab_id'
}],

// Procesos que se ejecutan conscutivamente después de guardar correctamente todos los datos del multiguardar
// También se lanza al clicar cancelar.
procesosPostEditar: []

},

refs: [
],

//
// Override del método en la classe del controller parent
// Función para forzar o no forzar los campos como obligatorios
//
camposDinamicos: function( panelEdicion, formulario ) {
var me = this;
//var formBasic = formulario.getForm();
//var ctrlCamposDinamicos = isoacademiaApp.getController('camposDinamicos');

// Valores de los campos del formulario que afectan a los dinámicos
// var regiso_contacto_id = formBasic.findField('regiso_contacto_id').getValue();
// var hayPdfAceptado = (formBasic.findField('hayPdfAceptado').getValue() == 'true'); // Ojo es un string.

//Ext.suspendLayouts();

// Si hay pdf aceptado mostrar boton "quitar pdf" / y el "ver imprimir"
// formulario.down('button[name="botonQuitarPdf"]').setVisible( hayPdfAceptado );
// formulario.down('button[name="botonImprimirPdf"]').setVisible( hayPdfAceptado );
// Si hay pdf aceptado boton subir tiene que poner "cambiar"
// formulario.down('button[name="botonUploaderPdf"]').setText( ( hayPdfAceptado ? gt.dgettext('isoacademia','Cambiar PDF aceptado...') : gt.dgettext('isoacademia','Subir PDF aceptado...') ));

// Campos obligatorios y no obligatorios segun condiciones.
// setCampoObligatorio (params) formBasic, campoNombre, obligatorio, autoOcultar
// ctrlCamposDinamicos.setCampoObligatorio(formBasic, 'regiso_alaattde', regiso_contacto_id<=0, false );

// Campos editables y no editables segun condiciones.
// Los campos que son siempre editables no hace falta marcarlos
// setCampoEditable (params) formBasic, campoNombre, editable, autoOcultar

// // Si es una RE040102 confirmada no dejamos editar campos
// ctrlCamposDinamicos.setCampoEditable(formBasic, 'escoge_re040102_serie_codigo', !presupuestoConfirmada, false );

//Ext.resumeLayouts(true);
}

});


Second controller with the base functionality



//@charset UTF-8

Ext.define('isoacademia.controller.re040103.mant', {
extend: 'Ext.app.Controller',

// Añadir las propiedades y metodos del del patron rexxxxxx.mant a esta clase
// Ojo los métodos que estan definidos en esta clase , si existen en el patron, no se copian.
mixins:[
'isoacademia.controller.rexxxxxx.mant'
],

models:[
're040103'
],
stores:[
're040103'
],
views: [
're040103.mantEdicion'
],

init: function() {
var me = this;

// Ejecutar método del parent
this.callParent(arguments);

me.control({
'isoacademia_view_re040103_mantEdicion' : {
afterrender: me.onRenderFichaEdicion,
guardar: me.onGuardarAction,
cancelar: me.onCancelarAction
}
});

},

// Definir los nombres, configuraciones y otros valores del sub-controller
subconfig: {
nombreMinus: 're040103',
nombreMinusPlural: 're040103',
nombreMayus: 'Re040103',
nombreMayusPlural: 'Re040103',

nombreExtDirect: 'isoacademia_re040103',
directMetodoClonarPhpNombre: 'clonarRe040103',

modelNombre: 're040103',
modelPrefijoCampos: 're040103_',
storeNombre: 're040103',

viewMantEdicion: 're040103.mantEdicion',
viewMantEdicionAlias: 're040103_mantEdicion',
formularioObjNombre: 'formularioRe040103',

// Nombre del campo que se muestra al pedir confirmación para borrar
confBorrarMostrarCampo: 'regiso_id',

// validaciones para el pre-guardar
preGuardar: {
arrayCamposEscogeNombre: [], // Nombres de los campos que corresponden a un "escoge" en el formulario principal
arrayVentanasEscoge: [], // Ventanas escoge definidas en el grid principal
arrayViewMantSubfichas: ['re040103Lin_mantEdicion'] // Alias de los mantenimientos de las subfichas anidadas a la ficha principal
},

// Procesos que se ejecutan conscutivamente después de guardar (save) la ficha principal
procesosMultiGuardar: [{
nombre: 're040103Lin',
tipo: 'subfichasSync',
descripcionMinus: gt.dgettext('isoacademia','línea'),
descripcionMinusPlural: gt.dgettext('isoacademia','líneas'),
descripcionMayus: gt.dgettext('isoacademia','Línea'),
descripcionMayusPlural: gt.dgettext('isoacademia','Líneas'),
viewGridNombre: 're040103Lin.mantGrid',
viewGridAlias: 're040103Lin_mantGrid',
modelNombre: 're040103lin',
modelPrefijoCampos: 're040103lin_',
modelCampoEnlace: 're040103lin_recab_id'
}],

// Procesos que se ejecutan conscutivamente después de guardar correctamente todos los datos del multiguardar
// También se lanza al clicar cancelar.
procesosPostEditar: []

},

refs: [
],

//
// Override del método en la classe del controller parent
// Función para forzar o no forzar los campos como obligatorios
//
camposDinamicos: function( panelEdicion, formulario ) {
var me = this;
//var formBasic = formulario.getForm();
//var ctrlCamposDinamicos = isoacademiaApp.getController('camposDinamicos');
//Ext.suspendLayouts();
//Ext.resumeLayouts(true);
}

});



App.js



//@charset UTF-8

// Cargador dinamico
//<debug>
Ext.Loader.setConfig({
enabled: true,
disableCaching: false,
paths: {
// Cesi.ux (Controles propios cesi)
'Cesi.ux': '../../libs/extjs_cesi/Cesi/ux',
// Extjs (la carpeta ux normalmente viene en el codigo fuente de sencha dentro de examples)
// Plugins y extensiones extjs
'Ext.ux': '../../libs/ext/src/ux',
// Extjs
'Ext': '../../libs/ext/src'
}
});
//</debug>

Ext.require('Ext.app.Application');
Ext.require('Ext.direct.*');
Ext.require('Ext.data.*');
Ext.require('Ext.tip.*');
Ext.require('Ext.window.MessageBox');
Ext.require('Ext.util.Format');
Ext.require('Ext.layout.container.Border');
Ext.require('Ext.chart.theme.Base');

// Requires forzados para la compilacion o Ejecución en desarrollo
Ext.require('Ext.toolbar.Paging');
Ext.require('Cesi.ux.layout.component.field.BoxSelectField');
Ext.require('Cesi.ux.form.field.BoxSelect');

// Variables globales
var isoacademiaApp;
var directProvider;

// Funcion que se ejecuta cuando se ha cargado todo lo necesario de las extjs.
Ext.onReady(function(){

// Arreglar algunos bugs en las traducciones de botones Extjs
// Forzar idioma botones messagebox (bug ext)
if (Ext.MessageBox) {
Ext.MessageBox.msgButtons['ok'].text = Ext.MessageBox.buttonText.ok;
Ext.MessageBox.msgButtons['cancel'].text = Ext.MessageBox.buttonText.cancel;
Ext.MessageBox.msgButtons['yes'].text = Ext.MessageBox.buttonText.yes;
Ext.MessageBox.msgButtons['no'].text = Ext.MessageBox.buttonText.no;
}

// Cargar el proveedor de Ext.Direct con la configuracion de API
directProvider = Ext.direct.Manager.addProvider(Ext.app.isoacademia_REMOTING_API);

// Separador decimal y de millares
Ext.util.Format.decimalSeparator = '.';
Ext.util.Format.thousandSeparator = ',';

// Definir el Theme para los graficos
Ext.define('Ext.chart.theme.isoacademia_theme', {
extend: 'Ext.chart.theme.Base',
constructor: function(config) {
this.callParent([Ext.apply({
colors: ['#94AE0A', '#115FA6', '#A61120','#F0A50A','#D54679','#FFCC2B','#A66111']
}, config)]);
}
});

// Definir la MVC app principal (isoacademiaApp)
// Dominio de las clases js = isoacademia.xxxxxx
Ext.application({
name: 'isoacademia',
autoCreateViewport: false,
enableQuickTips: true,
appFolder: 'app',

controllers: [
// Controladores isoAcademia
'main', 'mainMenu', 'mainMenuEmpresa', 'mainStatusBar', 'listadoPartes', 'gridBase',
'camposDinamicos',
'preimpresos.escoge',
'empresas.escoge',
'contactos.escoge',
'direcciones.escoge',
'registrosIso.mant', 'registrosIso.filtrosGrid',
'registrosIso.imprimir',
'rexxxxxx.mant', 'rexxxxxxSubficha.mant', 'rexxxxxx.imprimir',
're040102.mant', 're040102Lin.mant', 're040102.imprimir',
're040103.mant', 're040103Lin.mant', 're040103.imprimir',
'configuracion.mant',
'configuracionEmpresas.mant',
'contadoresEmpresas.mant'
],

launch: function() {
var me = this;

// Guardar el objeto aplicacion en una variable global
isoacademiaApp = me;

// Añadir un listener al direct manager para que analice todos los datos que llegan y
// si vienen con el requiereLogin = true, abrir ventana de login.
directProvider.on({
data: function( provider, e, eOpts ){
if (e.result) {
if (e.result.requiereLogin) {
// Mostrar aviso para que haga login en eSInube
Ext.MessageBox.show({
title: gt.dgettext('isoacademia','Sesión.'),
msg: gt.dgettext('isoacademia','Debe iniciar sesión en eSInube.<br />Haga click en OK para cargar pantalla de entrada.'),
buttons: Ext.MessageBox.OK,
closable: false,
icon: Ext.window.MessageBox.WARNING,
modal: true,
fn: function( buttonId, text, opt) {
// Volver a cargar la pagina principal del esinube
window.location = '../../';
}
});
}
}
},
scope: this
});


// Comprobar si es necesario hacer login
Ext.isoacademiaDirect.isoacademia_sesiones.requiereLogin(function(response, event) {

if (response.requiereLogin) {
//winLogin = me.getView('login').create();
//winLogin.show();
// Mostrar aviso para que haga login en eSInube
Ext.MessageBox.show({
title: gt.dgettext('isoacademia','Sesión.'),
msg: gt.dgettext('isoacademia','Debe iniciar sesión en eSInube.<br />Haga click en OK para cargar pantalla de entrada.'),
buttons: Ext.MessageBox.OK,
closable: false,
icon: Ext.window.MessageBox.WARNING,
modal: true,
fn: function( buttonId, text, opt) {
// Volver a cargar la pagina principal del esinube
window.location = '../../';
}
});

} else {

// Añadir eventos a la aplicacion antes y despues de los pasos iniciales
me.addEvents('prePasosIniciales','postPasosIniciales');

// Mostrar máscara
Ext.getBody().mask(gt.dgettext('isoacademia','Cargando empresas autorizadas ...'));

// Asignar el store en la app para que siempre tengamos disponibles todos los tipos de registros iso
me.storeTiposRegisoDisponibles = Ext.create('isoacademia.store.tiposRegiso', {
storeId: Ext.id(),
autoLoad: false,
pageSize: -1
});
// Cargar empresas en el store
// Aunque el load será asíncrono se supone que dará tiempo suficiente antes de mostrar ninguna pantalla
me.storeTiposRegisoDisponibles.load({
//callback: function(records, operation, success) {
//}
});


// Al ser una aplicacion multiempresa, antes de ejecutar los pasos iniciales ni mostrar nada,
// hay que asegurarse que se ha cargado el store con las empresas disponibles
// Asignar el store para poder tener las empresas disponibles (Forzamos la creación de un objeto nuevo)
me.storeEmpresasDisponibles = Ext.create('isoacademia.store.empresasEscoge', {
storeId: Ext.id(),
autoLoad: false,
pageSize: -1
});

// Cargar empresas en el store
me.storeEmpresasDisponibles.load({
callback: function(records, operation, success) {
// Quitar máscara
Ext.getBody().unmask();

// Si se ha cargado correctamente, hacer los pasos iniciales
// Comprobar que al menos tiene una empresa permitida
if (success && records.length>0) {

// Evento previo a los pasos iniciales
if (me.fireEvent('prePasosIniciales')) {

//
// Ejecutar los pasos iniciales al entrar (incluye la creacion del view principal)
//
me.getController('main').pasosIniciales( me );

// Evento de pasos iniciales acabados
me.fireEvent('postPasosIniciales');
}

} else {
// Mostrar mensaje si no tiene ninguna empresa permitida para operar con esta aplicacion
Ext.MessageBox.show({
title: gt.dgettext('isoacademia','Empresas autorizadas.'),
msg: gt.dgettext('isoacademia','Lo sentimos, pero su cuenta de usuario, no tiene permiso para operar con ninguna empresa en esta aplicación.')
+ '<br />' + gt.dgettext('isoacademia','Compruebe también, que en el sistema existe al menos una empresa creada, y que dicha empresa tiene permisos para operar con esta aplicación.')
+ '<br />' + gt.dgettext('isoacademia','No puede entrar a la aplicación.'),
buttons: Ext.MessageBox.OK,
icon: Ext.MessageBox.WARNING,
closable: false,
icon: Ext.window.MessageBox.WARNING,
modal: true,
fn: function(btn, text, opt) {
// Cerrar ventana del iframe aplicacion
if (parent) {
if (parent.esinubeApp) {
var panelAplicaciones = parent.esinubeApp.escritorioPrincipal.down('panel[region=center][name="zonaEscritorio"]');
if (panelAplicaciones) {
var appsAbiertas = panelAplicaciones.query('esinube_view_windowIframe');
for (var i=0; i<appsAbiertas.length; i++) {
// COmprobar si el nombre del frame coincide con el window actual de la app
if ( appsAbiertas[i].down('[name="iframewebexterna"]').frameName == window.name ) {
// Cerrar ventana
appsAbiertas[i].close();
}
}
}
}
}
}
});
}

// Ya podemos destruir el store de empresas disponibles (no lo necesitamos mas, las empresas estan en el menu)
if (!me.storeEmpresasDisponibles.isDestroyed) {
if (me.storeEmpresasDisponibles.storeId) {
me.storeEmpresasDisponibles.destroyStore();
Ext.data.StoreManager.unregister(me.storeEmpresasDisponibles);
}
delete me.storeEmpresasDisponibles;
}

}
});
}
});
}

});

});