Mostrando entradas con la etiqueta ESS/MSS. Mostrar todas las entradas
Mostrando entradas con la etiqueta ESS/MSS. Mostrar todas las entradas

jueves, 9 de septiembre de 2010

Solución en la llamada al Gestor Documental de Meta4 desde Firefox en el ESS/MSS

En un cliente hemos tenido un problema a la hora de desplegar la página que permite ver documentos almacenados en el Gestor Documental de Meta4 en navegadores Firefox.

Concretamente al llamar a la página "sse_g0/ssco_view_document.jsp" se retorna desde un Meta4Object una URL que usa el servlet download_blob:

server:port/servlet/download_blob?task=SSCO_VIEW_DOCUMENT&item=SSCO_VIEW_DOCUMENT!SSCO_VIEW_DOCUMENT[0].PRP_LOAD_DOC&no-cache=true


La dirección parece correcta pero si os fijais, aparecen unos caracteres "#38;" justo después de cada "&". Bueno, pues esa serie de caracteres hacen que la página no despliegue el documento, dejandola en blanco y sin dar error alguno.

Lo que hemos hecho para que se pueda desplegar es añadir un "replace" vía javascript a la URL de la siguiente forma:

[...]
urlDoc = "";
//SIC; Solución al error al levantar con FireFox la nueva página
urlDoc = urlDoc.replace(/#38;/g,"");
[...]

Quizás no sea la forma más sencilla pero, de esta forma funciona, y si alguien sabe una forma mejor, estaré encantado de saber cómo.

Nota: que decir tiene que Meta4 no tiene certifcado el ESS/MSS en la versión en la que estamos por lo que si disponeis del nuevo Look&Feel del ESS/MSS no tengais este problema.

Nota2: en Internet Explorer no se reproduce este problema

miércoles, 25 de agosto de 2010

m4:executereportsec

En varios post he hablado de cómo generar reports en el ESS mediante el uso del tag m4:executereport. Esta forma genera un report en la ruta "temp" de los m4webservices, añadiendo un usuario, la sesión, el nombre del report como ruta al report en PDF que Meta4 genera, como se puede ver en la siguiente imagen:


Cuando generamos un informe en el ESS con este tag podemos ver la ruta en la barra de dirección:


La ruta es: https://xxxxxxxx/temp/SICDAVID_34589BAEC222C212B9FDAE65A1310EC260963EA355BB3EC92F69B88F8486FD77/reports/CSL_RP_GNRAL_EVALUACION/CSL_RP_GNRAL_EVALUACION.pdf

Esta forma de generar un report tiene una seríe de problemas:

  1. Si la sesión no finaliza correctamente no se borran los informes

  2. Ocupa espacio en disco físico

  3. Si el nombre de usuario tiene caracteres especiales (espacios, "ñ"'s,...) , en UNIX/AIX, no se permite la impresión del informe porque el File System es incapaz de localizarlos.

  4. Poco seguro, si no se borran los ficheros alguien podría tener acceso a ellos y ver un Recibo de nómina, un Certificado de Haberes, informes personales de evaluaciones,...
Por ello y desde hace algún tiempo, a los informes/reports en el SSE los llamo usando el tag m4:executereportsec, cuya llamada es exactamente igual, pero evito que se generen en una ruta del servidor.


La ejecución de esto informes se guarda en base de datos y, como se puede ver en la siguiente imagen, en la barra de dirección del browser (navegador) aparece una ruta un poco menos explícita ya que se utiliza el servlet download_blob:



La ruta es:
https://xxxxxxxx/servlet/download_blob?task=REPORTS&item=SRP_HTML!HTML_RPT[FIRST].HTTP_DATA_FILE&no-cache=true

Retomando un poco los problemas del tag m4:executereport
  1. si la sesión no finaliza correctamente no se borran los informes; ahora, como no se guardan en disco no hay que borrarlos.
  2. Ocupa espacio en disco físico; ahora, como no se guardan en disco no se ocupa nada.
  3. Si el nombre de usuario tiene caracteres especiales (espacios, "ñ"'s,...) , en UNIX/AIX, no se permite la impresión del informe porque el File System es incapaz de localizarlos; ahora, como no se guardan en disco no hay problemas de generación de rutas en disco.
  4. Poco seguro, si no se borran los ficheros alguien podría tener acceso a ellos y ver un Recibo de nómina, un Certificado de Haberes, informes personales de evaluaciones,... ahora, la ejecución es totalmente segura y nadie verá nada que no pueda o deba ver.
Espero que os haya servido!

lunes, 10 de mayo de 2010

Calcular responsable y su mail

Desde hace ya un tiempo los clientes me piden que, tras ciertas acciones de un empleado en el Portal del Empleado (SSE), se remita un correo de cortesía a su responsable avisando de esta acción. [Obviamente cuando son procesos fuera de los flujos estándar]

Bueno el tema podría ser realizar una pequeña carga de un nodo con la Unidad a la que el empleado pertenece, revisar su responsable, los emails de ambos y lanzar el mail, pero vamos a "simplificarlo" usando el Meta4Object estándar SSE_VALIDADORES.

Primero es necesario generar dos alias de Meta4Object, uno para el SSE_VALIDADORES y otro obviamente para el Meta4Object MAIL:

MAIL:


SSE_VALIDADORES:

Después crearemos un método, conectado, por ejemplo antes del PERSIST_TREE() con un código semejante a este:

SSE_VALIDADORES!SSE_VALIDADORES.BEGIN()
MsIdPersona = [campo del ID de la Persona i.e. STD_ID_HR]
SSE_VALIDADORES!SSE_VALIDADORES.SSE_CALC_EMAIL(MsIdPersona,"SSE_EMAIL")

MsMailEmpleado = SSE_VALIDADORES!SSE_VALIDADORES.SSE_EMAIL
MsEmpleado = SSE_VALIDADORES!SSE_VALIDADORES.SCO_GB_NAME
SSE_VALIDADORES!SSE_VALIDADORES.ID_HR_PAR = MsIdPersona
SSE_VALIDADORES!SSE_VALIDADORES.SSE_CALC_RESPONSABLE("WORKUNIT10")
MsIdPersonaResp = SSE_VALIDADORES!SSE_VALIDADORES.SSE_ID_PERSON_RESP
MsMailResponsable = SSE_VALIDADORES!SSE_VALIDADORES.SSE_EMAIL_RESP

Este código nos deja en:

  • MsEmpleado el Nombre del empleado
  • MsMailEmpleado el email del empleado
  • MsIdPersonaResp el ID del responsable
  • MsMailResponsable el email del responsable

Luego con generar un mail ya estaría:

MAIL!MAIL.COMPOSE()
MAIL!MAIL.FROM = MsMailEmpleado
MAIL!MAIL.CC = MsMailEmpleado
MAIL!MAIL.DESTINATION = MsMailResponsable
MAIL!MAIL.SUBJECT = "Aviso de cambio en ...."
MAIL!MAIL.BODY = "Este correo electrónico se remite de forma automática desde el Portal del Empleado para avisarte de que " + MsEmpleado + " ha realizado ..."
MAIL!MAIL.SENDALL()



Espero que os sirva!!

sábado, 6 de febrero de 2010

t-innova: Migración Vistas SQLServer2000 a SQLServer2005

Esta semana me he encontrado un problema importante al migrar un t-innova de un SQL Server 2000 a un 2005.

El principal problema ha sido el Collation o Intercalación; este concepto de hace referencia al patrón de bits utilizado para representar/almacenar cada carácter, y en consecuencia también se refiere a las reglas utilizadas para ordenar y comparar caracteres. Evidentemente, se trata de un concepto que afecta sólo a los campos de texto. Para más información leer este Link

Para T.innova, como indica en su documentación, el collation que se indica que tiene que tener es Sql_Latin1_General_CP1_CI_AS.
El ESS el collation que tiene que tener es el Tradicional_Spanish_CS_AS.

Estas Collations son incompatibles y si haces una Query que junte ambos entornos obtendrás un error del estilo: "Cannot resolve collation conflict for equal to operation"

La solución pasa por, sobre la base de datos del ESS, recrear las vistas que atacan contra la base de datos de Tinnova, para forzar el collation que tienen en nuestra base datos (ESS) de la siguiente forma:

CREATE VIEW [dbo].[M4_ACUMU_CERHAB_ST]
AS SELECT
A.ID_SOCIEDAD COLLATE Tradicional_Spanish_CS_AS,
A.ID_EMPLEADO COLLATE Tradicional_Spanish_CS_AS,
. . .
FROM M4T_ACUMULADO_RL A, M4T_ACUM_RL2_ST B
WHERE
. . . .
GO


Podemos obtener el script completo de las vistas (sino lo tenemos) mediante la herramienta de SQL Server: "Microsoft SQL Server Management Studio". Nos posicionaremos en la base de datos del ESS y generamos los scripts con la opción "Generar secuencias de comandos".

Ahora que tenemos el script, tenemos el problema saber que campos son los que son afectados por el cambio de COLLATION en vistas que suelen ser "select * from"

Así que probe a hacer otras cosas... cambiar el collation de la base de datos del ESS, que se cambia, pero no los objetos que ya existieran, crear una BD nueva crear las tablas con un script optenido con "Generar secuencias de comandos", cargar los datos usando bcp o RAMDL,... pero nada obtenía errores.

Así que me puse a ver como estaban definidas las vistas y lo conseguí... (una semana depués pero en fin)
  1. Necesito saber las vistas y las columnas que usa el portal y que apuntan a EMIND:
    select a.name, b.name, b.xusertype, c.name
    from sysobjects a, syscolumns b, systypes c
    where
    a.xtype = 'V'
    and a.name not in('M4VCH_CONCEPTS', 'M4VCH_ITEMS', 'M4VCH_PI_COMP_TP', 'M4VCH_PICOMPONENTS', 'M4VDC_FIELDS','M4VDC_TIS_OWNER_T3', 'M4VDC_TIS_T3','M4VWP_OUTPUT_REP')
    and a.id = b.id
    and b.xtype = c.xtype
    order by a.name


    [El not in está creado viendo las vistas que son de PeopleNet]
  2. Luego las he llevado al excel "Migracion Vistas SQLServer2000 a SQLServer2005.xls" Hoja "VISTAS + COLUMNAS" (que os dejo en un link al final del articulo). Se pegan las 4 columnas de la vista en la columnas A,B,C,D (La D realmente no hace falta porque es informativa)
  3. En la Hoja "VISTAS ESPECIALES" ponemos en la columna A las vista que no son "SELECT *". En la columna "C" dejaremos la creación de estas vistas teniendo en cuenta el COLLATION.
  4. La propia columna H, de la hoja "VISTAS + COLUMNAS", nos da el script que hace la creación de todas las vistas teniendo en cuenta el nuevo Collation que dejaríamos en la celda B1=Traditional_Spanish_CS_AS.
  5. Para poder lanzar el script en SQL Server de forma masiva es necesario pegar en algun editor y cambiar ")" por ")[RET.CARRO]GO[[RET.CARRO]" (i.e., en Winword es: )^lGO^l)
  6. Antes de hacer creación será necesario crear el script de DROPs (os dejo mi ejemplo) de vistas y luego lanzar este más el de las tablas Especiales (os dejo mi ejemplo).

Y después todo a funcionado...

Hay teneis los archivos: Link

Si teneis dudas ... ya direis

[08/02/2010] Bueno, mi gozo en un pozo... al seguir haciendo pruebas, me he encontrado con un problema tras crear las vistas; ahora cuando intento insertar en las vistas, i.e.:

INSERT INTO M4T_ABSENTISMOS (COMENT, FEC_ALTA_EMPLEADO, FEC_ALTA_RECAIDA, FEC_FIN, FEC_FIN_RECAIDA, FEC_INI_RECAIDA, FEC_INICIO, ID_EMPLEADO, ID_SOCIEDAD, ID_TIPO_ABSENTISMO) VALUES (NULL, {d '2009-11-04'}, NULL, {d '2010-03-02'}, NULL, NULL, {d '2010-03-01'}, '02280481', '02', '9')

Obtengo otro error:

Mens. 4406, Nivel 16, Estado 1, Línea 1
Update or insert of view or function 'M4T_ABSENTISMOS' failed because it contains a derived or constant field.


Buscando por Google he visto que esto se deriba de intentar hacer inserts contra tablas que tengan algún campo calculado. [Recordemos que tras mis modificaciones inciales, cambiamos los select * de las vistas estándar de Meta4 por sus select campos]

He visto, en concreto en esta tabla que la columnas USUARIO, FEC_ULT_ACUALIZACION y HOSPITALIZACION se calculan al insertar, pero quitandolos de la vista sigo obteniendo el mismo error.

La solución pasa por generar triggers INSTEAD OF para que no se guarde en la vista sino a través de ella:


CREATE TRIGGER INSTEADOF_TR_I_M4T_ABSENTISMOS
ON M4T_ABSENTISMOS
INSTEAD OF INSERT AS
BEGIN
INSERT INTO LINK.EMIND.dbo.M4T_ABSENTISMOS (COMENT, FEC_ALTA_EMPLEADO, FEC_ALTA_RECAIDA, FEC_FIN, FEC_FIN_RECAIDA, FEC_INI_RECAIDA, FEC_INICIO, ID_EMPLEADO, ID_SOCIEDAD, ID_TIPO_ABSENTISMO)
SELECT COMENT, FEC_ALTA_EMPLEADO, FEC_ALTA_RECAIDA, FEC_FIN, FEC_FIN_RECAIDA, FEC_INI_RECAIDA, FEC_INICIO, ID_EMPLEADO, ID_SOCIEDAD, ID_TIPO_ABSENTISMO
FROM INSERTED

END

Con esto parece que todo va ok... habría que replicar este tipo de trigger (para INSERT, UPDATE y DELETE) para el resto de vistas y tablas que den problemas.



martes, 29 de diciembre de 2009

As Button Generator

Intentando cambiar algunos botones del ESS me he encontrado "googleando" [como me gusta este verbo] un generador on-line gratuito de botones: As Button Generator

As Button Generator tiene herramientas para definir tamaño, color y forma del botón, efectos en brillos y textos, relieves, sombras, tipo de fuente… miles de combinaciones para hacer un botón único listo para guardarlo en formato PNG y usarlo en vuestro proyecto.

Una excelente alternativa para los que no quieren pelearse con un editor de imágenes más complejo.

Espero que le podais sacar partido!!

jueves, 18 de junio de 2009

Capas de los menus del ESS/MSS en FireFox

Cuando desde un FireFox accedemos al ESS/MSS, no se despliegan las capas de los menú.
Para arreglar esto es necesario modificar dos cosas en los ficheros: default\libreria\menus_ess_esp.js y default\libreria\menus_mss_esp.js


  1. Esto creo que es un bug de Meta4: busca un literal que dice “odivmenu” y cambialo por “capa_menu”

  2. Esto ya es es para que la capa se dibuje un pelo más abajo de donde sale: busca un literal que dice “oparent.offsetTop + oparent.offsetHeight” y cambia esa línea:

}else{m4elemento(capa).style.top =(oparent.offsetTop + oparent.offsetHeight ) +"px";}
Por
}else{m4elemento(capa).style.top =(oparent.offsetTop + oparent.offsetHeight + 66) +"px";}
Ya está… el ESS/MSS listo para funcionar con el FireFox…

Nota: Meta4 aún no ha certificado FireFox, esto hace que la capas funcionen y por lo que he probado yo no hay mayor problema por cambiar de navegador…, pero es eso… lo que digo yo
Espero que os sirva!!

martes, 29 de julio de 2008

Query de Responsabilidad

Esta query/select la suelo usar mucho para calcular los ID de empleado que son responabilidad de un otro ID de empleado o de un ID de Usuario (normalmente un responsable de Unidad Organizativa).

La query en si misma devuelve la lista de Unidades Organizativas de las que es reponsable un manager y todas las que están por debajo jerárquicamente de éstas, mediante el Árbol de Unidades Organizativas definido en el cliente. Para ello se usa una tabla generalmente oculta que se llama M4SCO_WU_TREE (o de forma lógica: SCO_WORK_UNIT_TREE)

Tengo la versión que necesita el STD_ID_HR y STD_OR_HR_PERIOD:

SELECT DISTINCT
M4SCO_WU_TREE2.ID_ORGANIZATION,
M4SCO_WU_TREE2.SCO_ID_WU_CHILD
FROM
M4SCO_H_HR_RESP M4SCO_H_HR_RESP,
M4SCO_WU_TREE M4SCO_WU_TREE,
M4SCO_WU_TREE M4SCO_WU_TREE2
WHERE
M4SCO_H_HR_RESP.SCO_ID_HR = 'XXXXXX' AND
M4SCO_H_HR_RESP.SCO_OR_HR_PERIOD = X AND
M4SCO_H_HR_RESP.SCO_DT_START <= SYSDATE AND
SYSDATE <= M4SCO_H_HR_RESP.SCO_DT_END AND
M4SCO_H_HR_RESP.ID_ORGANIZATION = M4SCO_WU_TREE.ID_ORGANIZATION AND M4SCO_H_HR_RESP.STD_ID_WORK_UNIT = M4SCO_WU_TREE.SCO_ID_WU_CHILD AND M4SCO_WU_TREE.ID_ORGANIZATION = M4SCO_WU_TREE2.ID_ORGANIZATION AND M4SCO_WU_TREE2.SCO_LEFT_VALUE >= M4SCO_WU_TREE.SCO_LEFT_VALUE AND M4SCO_WU_TREE2.SCO_RIGHT_VALUE <= M4SCO_WU_TREE.SCO_RIGHT_VALUE
ORDER BY
M4SCO_WU_TREE2.ID_ORGANIZATION,
M4SCO_WU_TREE2.SCO_ID_WU_CHILD


y tengo la versión que necesita el ID_APP_USER:

SELECT DISTINCT
M4SCO_WU_TREE2.ID_ORGANIZATION,
M4SCO_WU_TREE2.SCO_ID_WU_CHILD
FROM
M4SCO_H_HR_RESP M4SCO_H_HR_RESP,
M4RSC_APPUSER M4RSC_APPUSER,
M4SCO_WU_TREE M4SCO_WU_TREE,
M4SCO_WU_TREE M4SCO_WU_TREE2
WHERE
M4RSC_APPUSER.ID_APP_USER = 'OSCARLG' AND
M4SCO_H_HR_RESP.SCO_ID_HR = M4RSC_APPUSER.ID_PERSON AND
M4SCO_H_HR_RESP.SCO_DT_START <= SYSDATE AND
SYSDATE <= M4SCO_H_HR_RESP.SCO_DT_END AND
M4SCO_H_HR_RESP.ID_ORGANIZATION = M4SCO_WU_TREE.ID_ORGANIZATION AND M4SCO_H_HR_RESP.STD_ID_WORK_UNIT = M4SCO_WU_TREE.SCO_ID_WU_CHILD AND M4SCO_WU_TREE.ID_ORGANIZATION = M4SCO_WU_TREE2.ID_ORGANIZATION AND M4SCO_WU_TREE2.SCO_LEFT_VALUE >= M4SCO_WU_TREE.SCO_LEFT_VALUE AND M4SCO_WU_TREE2.SCO_RIGHT_VALUE <= M4SCO_WU_TREE.SCO_RIGHT_VALUE
ORDER BY M4SCO_WU_TREE2.ID_ORGANIZATION, M4SCO_WU_TREE2.SCO_ID_WU_CHILD

Espero que os sirva... yo la uso mucho en el Meta4Object SSM_FILTRO.

Nota: Son para ORACLE, pero para SQL SERVER creo que con cambiar SYSDATE por GETDATE() funcionará igual.

lunes, 18 de febrero de 2008

Login Anónimo en el SSE

Hace poco en un cliente se me solicitó una solución para la siguiente funcionalidad: querían que un informe de descripción de funciones de las unidades organizativas de la compañía, que el Departamento de Personal disponía, en su momento dentro de Meta4PeopleNet, fuera solicitado desde la intranet de la empresa (no desde el SSE)...

Claro, se me ocurrieron algunas soluciones:
  • Sacar el informe de cada Unidad en PDF y dejarlo en el servidor de la intranet. El problema era que si del Dept. de Personal quería modificar algo... deberían entrar en PeopleNet, modificar los datos de la Unidad, generar el informe, y llevarlo al servidor de la intranet... (MALO, MALO!!!!)
  • Sacar el informe de cada Unidad en pdf y dejarlo en un campo blob de la base de datos de PeopleNet. El problema era que era necesario que se generara el informe en pdf cada vez que se modificara la información, y, además, para poder sacarlo sería necesario estar logado,...(REGULAR, REGULAR!!!!)
  • Pero, como os podeis imaginar por el nombre del post, la solución estaba aún por llegar. Es posible logarse al SSE de forma anónima y de esta forma hacer que según se pida la página de login anónimo (una que cree yo mismo) se ejecute un report desde el SSE... ESTA ES LA QUE ME GUSTO :)
Así que me puse a ello:
  • Crearemos una página, por ejemplo,: /sse_generico/espanol/uo_info.jsp que debe recibir un parámetro de la forma "?iduo=0001" y con un formulario que sea capaz de llamar al servlet de "Login" con un parámetro, y aquí está lo importante, "_TYPE_LOGON" con valor "ANONYMOUS".
<%
//Recogemos el parámetro
String sIDWorkUnit = request.getParameter("iduo");
%>

<form id="login_anonymous" name="login_anonymous" action="/servlet/login"
method="post">
<input size="15" type="hidden" id="_TYPE_LOGON" name="_TYPE_LOGON"
value="ANONYMOUS" />
<input type="hidden" id="_LANG" name="_LANG" value="3" />
<input type="hidden" id="_URL" name="_URL" value="/servlet/CheckSecurity/JSP/sse_generico/uo_report.jsp?iduo="<%=sIDWorkUnit%>/>
</form>

  • Luego con poner un submit de este formulario en el evento "onload" del tag "body" se enviaría este formulario, a través del login a la página: sse_generico/espanol/uo_report.jsp que sería la encargada de pasar el parámetro de la Unidad al informe...
  • El único "pero" es que hay que tener bien configurado el usuario ANONYMOUS dentro del configclient.xml (situado en [..]\M4WS\default\WEB-INF\classes\properties):


<ANONYMOUS>

<USER>ANONYMOUS</USER>

<PASSWORD>ANONYMOUSP</PASSWORD>

</ANONYMOUS>


Post relacionados: Obtener un Informe de Meta4 en el ESS/MSS (Link)

lunes, 28 de enero de 2008

Login avanzado para el ESS

La opción de usar el login avanzado del ESS nos permite poder modificar mucho el comportamiento de Meta4. Se usa cuando un usuario puede acceder con diferentes sociedades, roles, monedas o fechas.

Yo lo he usado para que se pueda cambiar de Rol de seguridad, de esa manera mantengo los usuarios/roles de PeopleNet y les añado nuevos roles... que luego eligen a acceder:

A ver si explico bien los pasos (a mi me sirvio estudiar el login avanzado del portal de tecnología):

  • En el login del portal de tecnología... (http://server:port/tctools/espanol/tc_login.jsp) tienes un link llamado "Login avanzado" cuando lo pulsas aparecen varías opciones para el cambio de sociedades, roles, moneda y fechas por defecto...



  • Desmarca la opción de roles por defecto y logate con un usuario que tenga opción de acceder con varios roles...

  • ...y aparecerá una nueva página como "Pop-up" que te permitirá elegir entre ellos...




  • Replica este comportamiento en tu login y ya está... (de forma sencilla básicamente es añadir un checkbox que por defecto esté marcado y que se envía dentro del form del login):

<input type="checkbox" checked="checked" name="CHANGE_ROLE" title="Cambio de perfil" onclick="var scam=login.CHANGE_ROLE.checked;if (scam==false){m4valor('login','M4_CHANGE_ROLE','1','set');}else{m4valor('login','M4_CHANGE_ROLE','','set');};">

Luego hay que tener en cuenta que las páginas a las que se pueda acceder deben tener dos includes más:

Al comienzo dentro del tag <head>: <%@ include file="/shco_g0/shco_gen_portal_code_begin.jspf" %>

Al final despues del tag </body>: <%@ include file="/shco_g0/shco_gen_portal_code_end.jspf" %>

para que te funcione bien.

Si hay alguna duda... ya sabeis por donde ando,

viernes, 18 de enero de 2008

Certificado de Haberes en PDF para el ESS - Portal del Empleado

(Ampliando el post: Obtener un informe de Meta4 en el ESS/MSS)

En estas fechas son muchos los clientes que nos piden que podamos sacar el Certificado de haberes en el Portal. En algunas versiones del Portal ya está incluído pero no sale en PDF de tal forma que un empleado pueda llevarselo e imprimirselo... (incluso sería posible firmarlo digitalmente usando librerias externas como iText)

Estos son los pasos para poder obtener el Certificado en PDF en el ESS.

  • Partimos del Meta4Object estándar "SSP_RP_CERT_HAB" o del que hayamo heredado en nuestro cliente:

  • Creamos en el nodo SSP_RP_C_HABERES una propiedad SSE_EJECUCION, de ámbito nodo, no visible, cadena variable de tamaño 1, con valor po defecto 0, que rellenaremos cuando ejecutamos el informe desde el ESS - Portal del empleado.

  • Creamos un Alias de Meta4Object (si no lo está creado ya) para el Meta4Object SCH_SESSION, en el nodo SSP_RP_C_HABERES, para recuperar el ID Persona del empleado logado al ESS - Portal del empleado.

  • Creamos un método también en el nodo SSP_RP_C_HABERES llamado SSE_FILTRO, ámbito nodo, tipo número de 1 posición entera, y que contendrá el siguiente código: link (NOTA: si tiene herencia hay que sobrescribir la regla para que tire del nodo que corresponda si dicho nodo está tocado)

  • Creamos el conector para que ejecute el método SSE_FILTRO antes del LOAD_PRG o de la LOAD_BLK (en la regla indicamos que si es del ESS - Portal del empleado ejecute dicho método y si no es del ESS - Portal del empleado que se quede como está).

  • Creamos un link en la página correspondiente desde la cual queremos ejecutar el Informe. Yo lo haré desde el portal (/sse_generico/espanol/generico_portal.jsp) mediante:

<li><a class="enlacefuncional" title="Certificado 10T" href="/servlet/CheckSecurity/JSP/sse_g2/sse_g2_certpdf.jsp?estado=21">Certificado 10T</a></li>

  • Creamos una página similar a la que aparece a continuación y que es llamada por el link de la anterior: sse_g2_certpdf.jsp (NOTA: Esta página puede mejorar sensiblemente, ya que aparece como un paso intermedio entre el link y la visualización del pdf. Si quisiera saltarse el paso no vale con un simple openwindow cuando se abre la página porque no le da tiempo al pdf a crearse y sale a medias. Deberíamos poner un retardo y luego abrir la página.)

Si usais una plantilla o logos o imágenes para "pintar" el certificado, recordad que esto archivos deben estar colocados en las rutas de reports (en la parte de color y b&w) del servidor de aplicaciones de Meta4 que genera el report/informe.

Espero que os salga bien y si alguien está interesado en saber como firmar digitalmente reports/informes de Meta4 en el ESS/MSS como este, que por favor, que deje un comentario en el post.

martes, 15 de enero de 2008

¿Cómo podemos obtener usuario Meta4 en Java?

He recibido algún mail pidiéndome que explique si es posible conocer el ESS/MSS o en JobSite el identificador del usuario conectado o del Rol con el que se conecta, la sociedad, etc.

Hay una forma realmente sencilla de hacer esto, para ello usaremos o los Atributos de la sesión de Java o las entradas de la Bolsa de parámetros de Meta4.

Parte común:

En el Meta4Object SSE_INICIO (caso del ESS/MSS de PeopleNet) en el Nodo SSE_INICIO crearemos una propiedad que llamaremos ID_APP_USER o ID_APP_ROLE o ID_APP_ORG, de ámbito nodo, no visible, tipo cadena variable de el tamaño que necesitemos en cada caso.

Luego en el método CARGA de la misma Estructura de nodo añadimos:
[..]
SSE_INICIO.ID_APP_USER = SCH_SESSION!ROOT_SESSION.ID_APP_USER
SSE_INICIO.ID_APP_ROLE = SCH_SESSION!ROOT_SESSION.ID_APP_ROLE
SSE_INICIO.ID_APP_ORG = SCH_SESSION!ROOT_SESSION.ID_ORGANIZATION

[..]
Obviamente, hay que tener definido un Alias al Meta4Object SCH_SESSION.

Pasamos ahora al entorno JSP. Hay dos páginas que se usan en el acceso al ESS/MSS; están, ambas, en sse_generico/[lang] que son generico_portal.jsp y generico_invisible.jsp.

Recuperaremos estos valores:
<%
M4SessionCl zsesion = M4Context.getM4SessionCl(request);
[..]
String zMeta4Object = "SSE_INICIO";
String znodo = "SSE_INICIO";
[..]
String zIDAPPUSER = "";
String zIDAPPROLE = "";
String zIDAPPORG = "";

try {
M4Operations m4opers = new M4Operations(request);
zIDAPPUSER = m4opers.getItem(znodo,zMeta4Object,znodo,"","ID_APP_USER");
zIDAPPROLE = m4opers.getItem(znodo,zMeta4Object,znodo,"","ID_APP_ROLE");
zIDAPPORG = m4opers.getItem(znodo,zMeta4Object,znodo,"","ID_APP_ORG");

//Usando entradas de la bolsa de Meta4
zsesion.putBagEntries("zIDAPPUSER", zIDAPPUSER);
zsesion.putBagEntries("zIDAPPROLE", zIDAPPROLE);
zsesion.putBagEntries("zIDAPPORG", zIDAPPORG );
} catch (Exception e) {}

//Usando atributos de la sesión de Java
session.setAttribute("zIDAPPUSER", zIDAPPUSER);
session.setAttribute("zIDAPPROLE", zIDAPPROLE);
session.setAttribute("zIDAPPORG", zIDAPPORG );
%>

Como podéis ver, la diferencia inicial es que en el caso de la Entradas de la Bolsa de Meta4 debemos capturar una posible “Exception” mientras que en el caso de los Atributos de la sesión de Java no hace falta.

A la hora de recuperar los valores almacenados también hay diferencias:
<% //Uso de Entradas en la Bolsa de meta4
M4SessionCl zsesion = M4Context.getM4SessionCl(request);
String zIDAPPUSER = zsesion.getBagEntries("zIDAPPUSER");
String zIDAPPROLE = zsesion.getBagEntries("zIDAPPROLE");
String zIDAPPORG = zsesion.getBagEntries("zIDAPPORG ");
%>
O
<% //Uso de Atributos en la sesión de Java
String zIDAPPUSER = (String) session.getAttribute("zIDAPPUSER");
String zIDAPPROLE = (String) session.getAttribute("zIDAPPROLE");
String zIDAPPORG = (String) session.getAttribute("zIDAPPORG");
%>
Como podéis ver también en el caso de los Atributos de la sesión de Java hace falta un “cast” para forzar al compilador que nos entregue un String.

Quizás a primera vista veáis que sea muy útil saber de un usuario su ID_APP_USER pero no veáis tan claro el uso de un Rol diferente al de por defecto, pero ¿habéis pensado que podríamos hacer con un usuario con varios roles o sociedades?, por ejemplo, usar el mismo usuario para el ESS/MSS y para los clientes de administración (Rich y Distribuido) pero que al entrar en el ESS/MMS pudiera elegir, como se hace en los clientes, con que rol accede, EMPLEADO, MANAGER, AUDITOR,… y así mostrar unas u otras opciones… Lo trataré en otro post.
Espero que os sirva...

viernes, 11 de enero de 2008

Obtener un Informe de Meta4 en el ESS/MSS

Muchas veces, los clientes nos piden que los Informes que hemos desarrollado para los entornos de clientes distribuidos (antes de la v7 de PeopleNet) o clientes ricos (desde la v7) puedan ser obtenidos en el ESS. Algunos ejemplos son el recibo de nómina, el Certificado de Haberes, recibos de las solicitudes hechas en el ESS (cursos de formación, préstamos,...), el currículum de empleados, ...

Meta4 PeopleNet provee de un mecanismo sencillo para poder obtenerlos através del tag m4:executereport.

Vamos a pensar en el siguiente caso… Digamos que el cliente nos pide poder obtener en el MSS, desde la página del “Curriculum Vitae del empleado” accesible desde la página “Datos personales de mis empleados” el Curriculum de sus empleados. Se podría usar el Informe ya existente del “Dossier del empleado” (SCO_RP_EMPLOYEE_DOSSIER) pero tiene mucha información que quizás no nos interese, así que lo haremos de otra forma, para ver los pasos uno a uno. Los pasos que realizaremos serán:

  • Crearemos un Meta4Object que recoja la información que necesitamos de las tablas de Persona (STD_PERSON) que pondremos como nodo Principal, eMail (STD_EMAIL), Teléfono (STD_PHONE_FAX), Dirección (STD_ADDRESS), Historial académico (STD_HR_ACAD_BACKGROUD), Experiencia profesional (STD_HR_PREV_JOBS) e Idiomas (STD_HR_LANGUAGES). Le llamare: CXX_CV_ESS y tendrá la siguiente estructura:
  • Como cosas especiales crearemos propiedad PRP_ID_PERSON (cadena variable de 9 caracteres, ámbito nodo y no visible, aunque mientras desarrollamos será mejor que sea visible y así podremos hacer pruebas) en el Nodo principal, que en la sentencia estará igualada a STD_ID_PERSON :

    SELECT @STD_ID_PERSON = A.STD_ID_PERSON, @STD_N_FAMILY_NAME_1 = A.STD_N_FAMILY_NAME_1, @STD_N_FIRST_NAME = A.STD_N_FIRST_NAME, @STD_DT_BIRTH = A.STD_DT_BIRTH, @STD_SSN = A.STD_SSN, @SCO_PHOTO = A.SCO_PHOTO
    FROM &STD_PERSON A
    WHERE (A.STD_ID_PERSON = @PRP_ID_PERSON)
  • Nota: Ojo con las fotos y archivos de imágenes… obviamente quedarán muy bien, pero hay que tener en cuenta que la ruta debe poder verla el SERVIDOR DE APLICACIONES que es donde se generará el Informe.
  • En las propiedades avanzadas de la estructura de nodo del nodo principal pondremos que puede ejecutar informes.
  • El siguiente paso es crear un Informe más o menos bonito… “para gustos los colores”. Le llamaremos CXX_RPT_CV_ESS.
  • Una vez que lo tengamos preparado, nos iremos a la página de “Curriculum Vitae del empleado”, “mss_g1_cv.jsp” de la carpeta “mss_g1/espanol”.

  • Añadiremos un nuevo link, por ejemplo debajo de “Consulta otros CVs” llamado “Descarga el CV (pdf)” de tal forma que al pincharlo se nos descargará el CV del empleado seleccionado. El código de este link sería:

<li><a class="enlacefuncional" title="Descarga el CV (pdf)" href="/servlet/CheckSecurity/JSP/mss_g1/mss_g1_p1_cv_pdf.jsp?zestado=11&amp;id=<m4:item"
m4name="SSE_EMP_CV!M4T_EMP_PERS_DATA.STD_ID_PERSON">">Descarga el CV (pdf)</a></li>

  • Ahora construiremos una nueva página en “mss_g1/espanol” llamada “mss_g1_cv_pdf.jsp”. El código pudiera ser el siguiente (link).

Repasaremos un poco las cosas importantes que tiene la página "mss_g1_cv_pdf.jsp”:

Líneas 6 y 7:

String zIdCV = request.getParameter("id");
String sParametros= "CXX_CV_ESS;CXX_CV_PERSON$CXX_CV_PERSON PRP_ID_PERSON \""+ zIdCV +"\"$";


Recogemos el parámetro enviado por la página padre y componemos un String de parámetros de la siguiente forma:

Meta4Object;Nodo Principal;Nodo de parámetros Propiedad_1 “Valor” ;Nodo de parámetros Propiedad_2 “Valor”$

Líneas 39-43:


function m4CVPdf(){
OpenReport('<m4:executereport idreport="CXX_RPT_CV_ESS" syssentence="<%=sParametros%>"
outputtype="PDF" otherparams="#/AUTOLOAD:DESIGN:OFF#"/>');
history.back();
}
window.setTimeout('m4CVPdf()',2000);

Lo que hace la función m4CVPdf() y la OpenReport(path), es levantar un path que nos devuelve la ejecución del tag m4:executereport en una nueva ventana, tras 2 segundos de espera (para darle un poco de tiempo a que se genere y se copie en la ruta /Temp/USER_SESSION/). Luego retorna a la página que lo ha llamado.

Lo importante de esta página, y de este post, es la llamada a este tag: m4:executereport cuyos atributos son idreport; donde indicaremos el nombre del informe que queremos ejecutar, syssentence; que son los parámetros del Meta4Obejct, outputtype; que puede ser PDF o HTML y otherparams; con parámetros de la generación de Informes.

El tag m4:executereport llama a la tarea M4THROW y ésta, usando los parámetros indicados, lanza la ejecución del Informe. Como todo Informe la carga se realiza usando la ROOTLOAD del nodo principal. Lo digo, porque es posible tocar los informes existentes para que antes de la LOAD_BLK o de la LOAD_PRG del nodo principal, podamos dar valor a ciertos parámetros, por ejmplo, al intentar levantar el recibo o el Certificado de Haberes le podemos decir que levante el recibo de la persona que esté logada en el ESS. (Tiene un poco más de trabajo pero pasa por enviar otro parámetro que indique si la ejecución se hace desde el ESS/MSS o si es desde un cliente que será el de por defecto.)

Si quereis probarlo lo mejor sería hacer primero algo pequeño, por ejemplo con solo información de la persona y luego ya añadiréis el resto de nodos.

Espero que os sirva...

miércoles, 12 de diciembre de 2007

Uso del servlet DownloadBlob en el ESS/MSS

Muchas veces nos encontramos con la necesidad de publicar documentos en el ESS o en el MSS que son "estáticos" por ejemplo un listado de personas, o una descripción de una unidad organizativa,...

Ante este caso podemos actuar de dos maneras:

Enlace HTML:
Dejamos el documento en las carpetas del servidor Web y referenciamos a ellas mediante un ancla o "anchor" de la siguiente forma href="/documents/documento.pdf".

  • Pros:
    Esto es lo más sencillo
  • Contras:
    1) no podemos controlar que ese link sea privado, por lo que cualquier persona podrá enlazar a ese documento de la forma http://server:port/documents/documento.pdf.
    2) si el usuario necesita modificar el documento, es muy probable, que tenga que pedirlo a otras personas para que se lo cuelguen. (O con los implantadores) (A no ser que lo montemos como un link en PeopleNet)
    3) el documento SIEMPRE se deberá llamar de la misma forma y tener la misma extensión ya que si no tendremos que modificar también la página.

Uso de Campo BLOB:
Usar el tipo Blob en un campo de una de nuestras tablas y ser capaz de descargarlo.

  • Pros:
    1) podemos controlar que ese link sea privado, ya que como la descarga se hace usando tecnología Meta4 es necesario estar logado al sistema.
    2) si el usuario necesita modificar el documento lo hará desde Meta4 PeopleNet.
    3) Se puede cambiar de nombre y extensión las veces que se quiera... Meta4 se encarga de la descarga y vuestro navegador de decidir que programa usa para abrirlo.
  • Contras:
    1) Es algo "más" complicado ya que hay que ser capaz de insertar ese documento en la Base de Datos
    2) Si el número de documentos es grande o esto son muy grandes podemos llenar la Base de Datos.
Este post trata, además de explicar porqué lo hago, describir la forma de poder llevar a cabo esta descarga.

Vamos a pensar en que debemos sacar la descripción de una Unidad Organizativa que es un documento que el usuario realiza y pasa luego a pdf y que lo quiere colgar del historial de puestos de los empleados, de tal forma que pinchando, o haciendo click, en un link el empleado pueda ver esta descripción, pero sólo de aquellas Unidades Organizativas por las que ha pasado a lo largo de su vida profesional.

Modelo de Datos: Lo primero sería, crear una tabla que, por ejemplo, se herede de STD_WORK_UNIT (También se puede hacer con un tabla con relación 1:1 con esta). A esta tabla le añadiremos un campo CXX_DESCRIPCION_BLOB con un tipo extendido basado en un BLOB.

Meta4Object: Crearemos un Meta4Object, llamémosle CXX_WUNIT_BLOB con un nodo y estructura de nodo que llame igual de tal forma que en la sentencia recojamos el STD_ID_WORK_UNIT y el campo CXX_DESCRIPCION_BLOB de la tabla que hemos creado en el paso anterior.
Añadiremos una propiedad PRP_ID_WORK_UNIT
Añadiremos un método "CXX_CARGA" con un parámetro ARG_ID_WORK_UNIT para poder recibir el ID Unidad Organizativa que más tarde enviaremos desde la página. El código podría ser: CXX_CARGA.txt


JSPs (ESS): Necesitaremos crear una nueva página sse_g3_desc_uo.jsp. Esta página recibirá un parámetro "iduo" que se pasará al Meta4Object: CXX_WUNIT_BLOB de la siguiente forma: sse_g3_desc_uo.jsp


De esta forma al entrar en esta página se lanzará la ejecución del servlet de la descarga del Blob

No he incluido nada que compruebe que esta Unidad organizativa tiene o no un documento que, creo que se debería.

Para la incluir un documento en un campo blob dedicaré otro post...o retocaré este en breve.