Mostrando entradas con la etiqueta Oracle JD Edwards. Mostrar todas las entradas
Mostrando entradas con la etiqueta Oracle JD Edwards. Mostrar todas las entradas

viernes, 1 de abril de 2022

[JD Edwards - BSSV] Import external JAVA library (ENG)

Hi jde friends,

Sometimes, we find ourselves with need to extend JD Edwards functionalities and we find many functionalities in JAVA packages or libraries, JAVA is one of the most languages and platform used in technologies. For example, recently I worked in a project to implement Bidimensional code QR. So, what is the JDE solution?


Well, we use a JAVA library to facilitate the coding. In this case IdAutomation (that is license paid, but there are other as Google (Zxing) and many other open source, depending on each case and use). So, this provider provides a java library in witch it has a class and a method for facility implementation, that we pass the string to be encoded and it return as array string encoded. Later, to this array we put a font in BIPublisher and we already have our encoded QR code. Easy right?

Then, we generated our BSSV object (and we cannot forget our BSFN in C to communicate our report or application with BSSV component), with our class and main method. But, how import IdAutomation QR library to our JD Developer project?

1. On our project, we press the rigth button and in the context menu click on Project Properties:

2. Press in Librares and Classpath menu and next press button Add JAR Directory

3. Select the JAVA library (I recommend leaving in the JDE Path JDE system\Classes (later I explain the reason)

4. Press on Open button in the dialog, and it is added to the project:

5. Press OK and save the project. We can use library classes and method importing to our java class.

               boolean bestMask = true;           // Best pattern mask
               
               String resultQREncode = qre.FontEncode(dataToEncode, applyTilde, encodingMode, errorCorrectionLevel, version, bestMask);
               internalVO.setSzQREncodedData(resultQREncode);
               
               printMsg(context, "Encoded => ");
               printMsg(context, resultQREncode);

And we have everything ready in our project!!!

To deploy, we have to configure system to use a external library for when compiling and generating deploy package it imports the external library in jar jde deploy package. This configuration is done in deploy server (although I also configure it in my fat client).

1. Copy the library to system\Classes folder:

2. Modify the file sbffoundation.ini inside the same folder, in the section [Foundation] y and add a line "LIB" + "next sequence" + "=" + "library name"

And with this we already our BSSV project with an external library ready to deploy!

Pd: I have also used an external library for Datamatrix code, integrate with Webcenter Content through RIDC standard java package, and recently to create a proxy client webservice through an external library with java wsimport command to integrate with Salesforce that you can see here.

Good code JDE Friends!

sábado, 19 de febrero de 2022

[JD Edwards] Form Charts - ChartControl Component (ENG)

Hola jdedwerds,

I recently worked on a project where we needed to display KPI's of sales orders processed automatically, so beside showing the boring tables with the processed orders info and the percentage calculation in certain fields, I thought of adding a graph which is always more visually pleasing.

This time I have done it natively, it's true that we have had this tool for quite some time but I've rarely seen it used even in a standard apps - on the P41021 availability app and on some planning/production applications- and I don't understand why (it are not the most powerful charts for that there are other tools, but for simple cases use it should be enough)

It's true that we have other tools in the environment itself such as One View Reporting OVR or that KPI's are usuarlly analyzed in business with Business Intelligence BI tools, but why not give them a touch of color to our JDE applications??




The first thing to do is to insert a ChartControl in our form:



Then, in the event where we have the information to display (after reading each grid line, at the end of the grid, etc.) we create a variable to load the XML tags needed for the chart -in my case a foot chart-. Then, we load the information to the chart through the Set Data XML function available in the Chart Control Functions section of the System Functions. And finally, we perform the action to draw the chart with the Draw Chart function avaible in the same section previously seen:




Therefore, the code would like this:


The following chart types are available:

  • bar_basic
  • bar_basic_percent
  • cluster_bar_basic
  • combo_basic
  • line_basic
  • pie_basic
  • pie_ontime
  • stacked_bar_basic
  • stacked_bar_ontime

We can perform visualization tests of graphs and examples created in our installation on our web server with the resource http://<webhost>:<webport>/jde/GraphPrototype.maf




For more oficial information in the next link: https://support.oracle.com/epmos/faces/DocumentDisplay?id=648865.1

The next thing I want to integrate are external charts from Google Charts, through a TextBlock and with the API's provided by Google. I'll try to make a POC, soon.

I hope you found it interesting and useful.

Best regards.

Alfredo.

viernes, 18 de febrero de 2022

[JD Edwards] Gráficos Formularios - Componente ChartControl (ESP)

Hola jdedwerds,

Recientemente trabajé en un proyecto donde necesitaba mostrar unos KPI's de pedidos de ventas procesados automáticamente, por lo que aparte de mostrar las aburridas tablas con la info de pedidos procesados y el cálculo del porcentaje en ciertos campos, se me ocurrió añadir una gráfica que siempre resulta más agradable visualmente. 

Ésta vez lo hice de manera nativa, es cierto que tenemos desde hace bastante tiempo ésta herramienta pero pocas veces la he visto ser utilizada incluso de manera estándar -en pantalla disponibilidad P41021 y en algunas de planificación/producción- y no entiendo el motivo (no son las gráficas más potentes para eso existen otras herramientas, pero para un uso y casos sencillos debería ser suficiente).. 

Es cierto que disponemos de otras herramientas en el propio entorno como One View Reporting OVR o que normalmente los KPI's se analizan en negocio con herramientas de Business Intelligence BI, pero por qué no darles un toque de color a nuestras pantallas JDE??




Lo primero que debemos realizar es insertar un ChartControl en nuestro formulario:



A continuación en el evento donde dispongamos de la información para mostrar (después de leer cada línea, al finalizar el grid, etc.), lo que haremos será crear una variable para cargar las etiquetas XML necesarias para el gráfico -en mi caso un gráfico de pie-. Posteriormente, cargamos la información al gráfico a través de la función Set Data XML disponible en la sección Chart Control Functions de las System Functions. Y finalmente realizamos la acción para que se dibuje el gráfico con la función Draw Chart disponible en la misma sección anteriormente vista:




Por lo cual, el código quedaría tal que así:


Disponemos de los siguientes tipos de gráficos:

  • bar_basic
  • bar_basic_percent
  • cluster_bar_basic
  • combo_basic
  • line_basic
  • pie_basic
  • pie_ontime
  • stacked_bar_basic
  • stacked_bar_ontime

Podemos realizar pruebas de visualización de gráficas y ejemplos creados en nuestra instalación, en nuestro servidor web con el recurso http://<webhost>:<webport>/jde/GraphPrototype.maf




Para más información oficial en el siguiente enlace: https://support.oracle.com/epmos/faces/DocumentDisplay?id=648865.1

Lo siguiente que quiero integrar son gráficas externas de Google Charts, mediante un TextBlock y con las API's facilitadas por Google. Intentaré hacer una POC, próximamente.

Espero les haya resultado interesante y útil.

Un saludo,

Alfredo.

jueves, 25 de febrero de 2021

[JD Edwards - BSSV] Importar librería JAVA externa (ESP)

 Hola amigos,

En ocasiones, nos encontramos con la necesidad de extender la funcionalidad de nuestro JDE y muchas funcionalidades nos la encontramos en paquetes o librerías externas JAVA ya que es uno de los lenguajes y plataformas más extendidos. Por ejemplo, recientemente trabajé en un proyecto para implementar códigos bidimensionales QR. Entonces, ¿cuál es la solución?


Pues utilizamos una librería JAVA para facilitar la codificación, en éste caso una de IdAutomation que es de pago, pero hay otras de Google (Zxing) y otras muchas open source, depende cada caso y uso.
Pues bien, éste proveedor facilita una librería java en el cuál tiene una clase y un método que le pasamos el string a codificar y nos devuelve un array codificado. Posteriormente, a éste array le ponemos una fuente y ya tenemos nuestro código QR codificado. Fácil ¿verdad?

Entonces, generamos nuestro objeto BSSV (y no nos olvidemos nuestra BSFN en C para luego comunicarnos desde nuestro report o aplicación), con nuestra clase y método principal. Pero ¿Cómo importamos nuestra librería en nuestro entorno JDeveloper? 

1. Sobre nuestro proyecto, pulsamos botón derecho y en el menú Project Properties...:

2. Pulsamos sobre el menú en Libraries and Classpath, y dentro de éste sobre Add JAR/Directory:


3. Seleccionamos nuestra librería (recomiendo dejarla en la ruta JDE system\Classes (y luego explico el motivo)

4. Pulsamos sobre Open/Abrir, se nos añade a nuestro proyecto

5. Pulsamos OK, y guardamos el proyecto. Ya podremos utilizar las clases y métodos de la librería externa importándolas a nuestro código.

               boolean bestMask = true;           // Best pattern mask
               
               String resultQREncode = qre.FontEncode(dataToEncode, applyTilde, encodingMode, errorCorrectionLevel, version, bestMask);
               internalVO.setSzQREncodedData(resultQREncode);
               
               printMsg(context, "Encoded => ");
               printMsg(context, resultQREncode);

Y ya tendríamos todo listo en nuestro proyecto!

Para desplegar, tenemos que configurar a nivel de sistema que usamos una librería externa para que a la hora de compilar y que genere el paquete de despliegue, importe nuestra librería. Ésta configuración se realiza en el servidor Deploy (aunque yo también la configuro en mi cliente pesado).

1. Copiamos nuestra librería en la carpeta system\Classes de nuestra instalación:

2. Modificamos el fichero sbffoundation.ini dentro de la misma carpeta, en la sección [Foundation] y añadimos una línea con "LIB" + "siguiente secuencia" + "=" + "Nombre de nuestra librería"

Y con esto ya tendríamos nuestro proyecto de BSSV con una librería externa lista para desplegar!

PD: he utilizado librería externa también para código Datamatrix, para integrar con Webcenter Content a través de RIDC, y recientemente para crear un webservice proxy client a través de una librería externa con wsimport que pondré próximamente en un post.

Buen código JDE Friends!

martes, 5 de noviembre de 2019

[JD Edwards] Asign Icon to Cell Grid

Hi Friends,

When we show data in grid in application, it could be very cross and relevants, but often not very attractive. In JDE we can assign icons to cells to make it visually more attractive and to have a more global idea about the information shown.


How do we do this?

On the one hand, we use Set Grid Cell Icon system function, but attention! this function is only availabe in Business Functions NER type. This function has only 2 parameters:



  •  Image File: image selected to show. We position ourselves in the parameters, click on <Image Picker> and select an icon of the available Bitmaps of the system. ¿Could we add custom images? Of course, but for that we would have to add them previously to the system bitmaps.
  •  Icon Tooltip: as tooltip  we can pass a literal text or assign the description of a data dictionary text (type Error Message).


But, How do I assign it to a column?

The first thing we will have to do is modify in the properties of the same column in Display Style is assign Type Icon.

With this option an event is enabled in the column "Grid Cell Display Changed" where we will call our BSFN to display the icon. Of course, remember that it will only be displayed on the web.

Do I have to do this for each icon I want to display?

The answer is depends on how you put it, there are currently numerous standard functions where they are already implemented. As examples:
  • N43S003 - Load Grid Cell Icon
  • N3201990 - Message Center Icons
  • N0900730 - Set Delete Icon
  • N40G1240 - Set Edit Icon
  • N98220 - Set Grid Icon Web
  • N986110B - Set Grid Icon
  • etc
Must of these functions already have input parameters to show some icons or others depending on the input parameters, or else you can create your own BSFN NER Custom!!!

An example of mine to show attachments with a custom structure at the header level:
JD Ewards Grid Cell Icon
JD Ewards Grid Cell Icon

I hope it will be you useful!

Let's go!






[JD Edwards] Asignar Icono a Columna en Grid

Hola amig@s,

Cuando mostramos en una aplicación los datos en un grid, éstos pueden ser muy transcendentales y relevantes pero a menudo no muy atractivo. En JDE podemos asignar iconos a columnas para hacerlo visualmente más atractivo y poder tener de un vistazo una idea más global acerca de la información mostrada.

¿Cómo hacemos ésto?

Por un lado, utilizamos la función de sistema Set Grid Cell Icon, pero atención! ésta función sólo está disponible en Business Functions tipo NER. Ésta función sólo tiene 2 parámetros:



  •  Image File: imagen seleccionada para mostrar. Nos posicionamos en el parámetros, clickamos sobre <Image Picker> y seleccionamos un icono de los Bitmaps disponibles del sistema. ¿Podemos añadir imágenes personalizadas? Por supuesto, pero para ello tendríamos que añadirlas previamente a los bitmaps del sistema.
  •  Icon Tooltip: como tooltip podremos pasar un texto literal o asignar la descripción de un diccionario de texto (tipo Erro Message).


¿Pero cómo se lo asigno a una columna?

Lo primero que tendremos que hacer es modificar en las propiedades de la misma columna en Display Style asignar tipo Icon.

Con ésta opción se nos habilita un evento en la columna "Grid Cell Display Changed" donde llamaremos a nuestra BSFN para mostrar el icono. Por supuesto, recordar que sólo se mostrará en web.

¿Tengo que hacer ésto para cada icono que quiera mostrar?

La respuesta es depende cómo lo plantees, actualmente existen numerosas funciones estándar donde ya están implementadas. Como ejemplos:


  • N43S003 - Load Grid Cell Icon
  • N3201990 - Message Center Icons
  • N0900730 - Set Delete Icon
  • N40G1240 - Set Edit Icon
  • N98220 - Set Grid Icon Web
  • N986110B - Set Grid Icon
  • etc
La mayoría de éstas funciones ya tienen parámetros de entrada para mostrar unos iconos u otros en función de los parámetros de entrada, y sino puedes montarte tu propia BSFN NER Custom!!!

Un ejemplo mío para mostrar anexos con una estructura custom a nivel de cabecera:
JD Ewards Grid Cell Icon
JD Ewards Grid Cell Icon

Espero les sea de utilidad!

Let's go!






lunes, 18 de julio de 2016

[JD Edwards] Custom Login Page

If you want customize your E1 Login Page you can access to resources in the next directory in web server:

/u01/oracle/middleware/oracle_home/user_projects/domains/e1_domain/servers/JASPD/stage/JASPD/app/webclient.war/share

When:
- /u01/oracle/middleware/oracle_home/: is a JD Edwards installation (in my case 9.2 tools)
- JASPD: web instance

In share directory you can find all resources as images (backgrounds, icons, etc.), pages, scripts, etc.

For example, I changed tipically "watermark-oracle.png" for a custom image as background.

It is cool!!!!

[JD Edwards] Personalizar Página Login

Si quieres personalizar tu página de login de E1 tu puedes acceder a sus recursos en el siguiente directorio del servidor web:

/u01/oracle/middleware/oracle_home/user_projects/domains/e1_domain/servers/JASPD/stage/JASPD/app/webclient.war/share

Donde:
- /u01/oracle/middleware/oracle_home/: es la instalación de JD Edwards (en mi caso tools 9.2)
- JASPD: instancia web

En el directorio share, tu puedes encontrar todos los recursos como imágenes (fondos, iconos, etc.), páginas, scripts, etc.

Por ejemplo, yo cambié el típico "watermark-oracle.png" por una imagen personalizada como fondo:

Ésto es chulo!!!!

lunes, 4 de julio de 2016

[SQLDeveloper] Open multiple tables

When working with databases, we usually use IDE applications for work more comfortable. With Oracle Database the most common is SQLDeveloper

SQLDeveloper allow us doing SQL sentences and graphically display database components: tables, views, triggers, procedures, functions, packages, etc.

Also, when we working with tables, we need view one or more tables at the same time. With SQLDeveloper default configuration each time when we open a table overwrite the same tab of table that we were viewing.

For change the configuration and we can view the tables in different tabs, it's very comfortable, there are activate the next check in preferences:

Tools->Preferences->Data Base-> Object View->Automatically Freeze Object Viewer Windows




And in this way we will see in different tabs:



I hope it will be useful for you!!!

[SQLDeveloper] Abrir varias tablas a la vez

Cuando trabajamos con base de datos, solemos utilizar un IDE para trabajar más cómodamente. Con base de datos Oracle el más habitual es SQLDeveloper.

SQLDeveloper nos permite realizar sentencias SQL así cómo visualizar gráficamente los componentes de la base de datos: tablas, vistas, disparadores, procedimientos, funciones, paquetes, etc.

Además, cuando trabajamos con tablas habitualmente necesitaremos consultar o realizar varias tablas a la vez. Con la configuración por defecto de SQLDeveloper cada vez que abrimos una tabla nos sobreescribe en la misma pestaña la que teníamos visualizando anteriormente.

Para cambiar la configuración y ver todas las tablas en diferentes pestañas, lo cual es bastante cómodo, hay que activar el siguiente check en preferencias:

Herramientas -> Preferencias -> Base de Datos -> Visor de Objetos -> Congelar Automáticamente Ventanas del Visor de Objetos




Y de ésta manera lo veremos en pestañas diferentes:



Espero os sea útil!!!

[JD Edwards] Reserva de Objeto

Cuando un usuario está trabajando con un documento y lo está editando, deberíamos siempre no permitir que ningún otro usuario pueda modificarlo para no se produzca incongruencias. Ésto es lo que se conoce como Reserva de Objetos o Reserva de Documentos.

En JDE en la mayoría de pantallas estándar ésto está implementado, pero cuando creamos una pantalla custom deberíamos tenerlo en cuenta.

¿Cómo JDE realiza ésto?

Muy sencillo, lo que simplemente hace es cuando alguien se propone a editar un documento inserta un registro en la tabla F00095 y no lo elimina hasta que el usuario abandona la edición. De ésta manera, cuando otro usuario entra en otra instancia de la misma aplicación comprueba si existe el registro en la tabla F00095, de ser así muestra un error y bloquea para no permitir editar.

¿Qué hay que hacer?


Bien, entonces utilizando la función estándar "F00095 Reserve Object" con el UKID "RRESERVE", y normalmente con los valores claves del documento que estemos trabajando, ésta función realiza 2 cosas: por un lado comprueba si ya está reservado o no, y en caso de que no inserta el registro, o lo que es lo mismo lo reserva. En caso de que esté reservado, utilizamos la función "Set Object Reservation Text Substitution Error" para mostrar un error en la pantalla y además sería más deseable y más limpio que bloqueáramos todos los campos de la pantalla.

Ejemplo:


0080       //
0081       //  # Reserva #
0082       //
0083       // Cogemos un UKID (RRESERVE) de la F00022
0084       //
0085       Get Next Unique Key ID
              "RRESERVE" -> BF szObjectName
              VA frm_UniqueKeyIDInternal_UKID <- BF mnUniqueKeyID
0086       //
0087       // Lo convertimos a string para pasarselo a la función de reserva parámetro
0088       // PID
0089       //
0090       Math Numeric to String, Convert
              VA frm_UniqueKeyIDInternal_UKID -> BF mnMathNumeric01
              VA frm_szUniqueIDRecReserve_PID <- BF szVideoConstant30A
0091       //
0092       // Cogemos como clave el id de incidencia
0093       //
0094       VA frm_GenericKey_GENKEY = [FI mnIdentificadorIncidencia]
0095       //
0096       // Lo reservamos, pasándole usuario, clave, tabla, PID Único
0097       //
0098       F00095 Reserve Object
              "F55N42IC" -> BF szNameObject
              VA frm_UserId_USER -> BF szUserId
              "1" -> BF cSuppressErrorMessage
              VA frm_szRecordReserveErrMsg_DTAI <- BF szErrorMessageID
              VA frm_ReserversNameAlpha_ALPH <- BF szReserversNameAlpha
              VA frm_GenericKey_GENKEY -> BF szGenericKey
              VA frm_szUniqueIDRecReserve_PID -> BF szApplication
              VA frm_szReserversAplication_PID <- BF szReserversApplication
              "1" -> BF cWarningError
0099       //
0100       // Si está reservado, nos lo indicará en ErrorMesageID. Entonces mostramos
0101       // error y deshabilitamos el OK y los campos
0102       //
0103       If VA frm_szRecordReserveErrMsg_DTAI is not equal to <Blank> And VA frm_szRecordReserveErrMsg_DTAI is not equal to <Null>
0104          Set Object Reservation Text Substitution Error
                 VA frm_ReserversNameAlpha_ALPH -> BF szReserversNameAlpha
                 VA frm_GenericKey_GENKEY -> BF szGenericKey
                 VA frm_szReserversAplication_PID -> BF szApplication
                 "2" -> BF cWarningError
0105          Disable Control(HC &OK)
0106          Disable Control(FC 2nd Address Number)
0107          Disable Control(FC Address Book Name)
0108          Disable Control(FC Electronic Address)
0109          Disable Control(FC Phone Number)
0110          Disable Control(FC Fuente Incidencia)
0111          Disable Control(FC Motivo Incidencia)
0112          Disable Control(FC Estado Incidencia)
0113          Disable Control(FC Departamento Incidencia)
0114          Disable Control(FC Comment)
0115          Disable Control(FC Conclusión)
0116       End If

Por supuesto, una vez que finalicemos con la edición (cuando pulsemos el botón OK o Cancel normalmente), tenemos que quitar la reserva (el registro de la F00095) para que no se quede bloqueado y podamos editarlo a futuro mediante la BSFN "F00095 Remove Business Object Reservation".

Ejemplo:

0040    // # Quitamos la reserva
0041    //
0042    // Si la variable PID devuelta es blanco, es porque lo hemos reservado, por lo
0043    // tanto quitamos la reserva pasando el usuario, tabla, clave y PID con el UKI
0044    // unico
0045    //
0046    If VA frm_szReserversAplication_PID is equal to <Blank>
0047       F00095 Remove Business Object Reservation
              VA frm_UserId_USER -> BF szUserId
              "F55N42IC" -> BF szNameObject
              VA frm_GenericKey_GENKEY -> BF szGenericKey
              VA frm_szUniqueIDRecReserve_PID -> BF szApplication
0048    End If
0049    //


Y con ésto minimizamos el impacto de que varios usuarios a la vez trabajen con el mismo documento, algo muy simple y que nos puede evitar de bastantes problemas a futuro!

[JD Edwards] Object Reserve

When a user is working and editing a document, we shouldn't allow other users can modify to avoid inconsistences. It is know as Object Reserve o Document Reserve in JD Edwards.

In the most standard JDE Applications it is implment, but when we create a custom application we should keep in mind

How it's made?

It's easy, jde simply insert a row in F00095 table when a user edit the document, and not deleted until user exit from edition. In this way, when other user in in another application instance check if exist the row in F00095 table, if is true show a error and blocking fields for not allow edit.

What is there to do?


Using "F00095 Reserve Object" business function standard with the UKID "RRESERVE", and normally with document keys values, this function doing 2 things: check if it is reserved or not, if not it reserverd insert a row and reserve. If it reserved, use the bsfn "Set Object Reservation Text Substitution Error" for set a error, and blocking all field of application.
Sample:


0080       //
0081       //  # Reserva #
0082       //
0083       // Cogemos un UKID (RRESERVE) de la F00022
0084       //
0085       Get Next Unique Key ID
              "RRESERVE" -> BF szObjectName
              VA frm_UniqueKeyIDInternal_UKID <- BF mnUniqueKeyID
0086       //
0087       // Lo convertimos a string para pasarselo a la función de reserva parámetro
0088       // PID
0089       //
0090       Math Numeric to String, Convert
              VA frm_UniqueKeyIDInternal_UKID -> BF mnMathNumeric01
              VA frm_szUniqueIDRecReserve_PID <- BF szVideoConstant30A
0091       //
0092       // Cogemos como clave el id de incidencia
0093       //
0094       VA frm_GenericKey_GENKEY = [FI mnIdentificadorIncidencia]
0095       //
0096       // Lo reservamos, pasándole usuario, clave, tabla, PID Único
0097       //
0098       F00095 Reserve Object
              "F55N42IC" -> BF szNameObject
              VA frm_UserId_USER -> BF szUserId
              "1" -> BF cSuppressErrorMessage
              VA frm_szRecordReserveErrMsg_DTAI <- BF szErrorMessageID
              VA frm_ReserversNameAlpha_ALPH <- BF szReserversNameAlpha
              VA frm_GenericKey_GENKEY -> BF szGenericKey
              VA frm_szUniqueIDRecReserve_PID -> BF szApplication
              VA frm_szReserversAplication_PID <- BF szReserversApplication
              "1" -> BF cWarningError
0099       //
0100       // Si está reservado, nos lo indicará en ErrorMesageID. Entonces mostramos
0101       // error y deshabilitamos el OK y los campos
0102       //
0103       If VA frm_szRecordReserveErrMsg_DTAI is not equal to <Blank> And VA frm_szRecordReserveErrMsg_DTAI is not equal to <Null>
0104          Set Object Reservation Text Substitution Error
                 VA frm_ReserversNameAlpha_ALPH -> BF szReserversNameAlpha
                 VA frm_GenericKey_GENKEY -> BF szGenericKey
                 VA frm_szReserversAplication_PID -> BF szApplication
                 "2" -> BF cWarningError
0105          Disable Control(HC &OK)
0106          Disable Control(FC 2nd Address Number)
0107          Disable Control(FC Address Book Name)
0108          Disable Control(FC Electronic Address)
0109          Disable Control(FC Phone Number)
0110          Disable Control(FC Fuente Incidencia)
0111          Disable Control(FC Motivo Incidencia)
0112          Disable Control(FC Estado Incidencia)
0113          Disable Control(FC Departamento Incidencia)
0114          Disable Control(FC Comment)
0115          Disable Control(FC Conclusión)
0116       End If

Of course, when user finished edition (when click OK or cancel button normally), we have to remove reserve (F00095 row) for not blocking and the users could edit in a future by the BSFN "F00095 Remove Business Object Reservation".

Sample:

0040    // # Quitamos la reserva
0041    //
0042    // Si la variable PID devuelta es blanco, es porque lo hemos reservado, por lo
0043    // tanto quitamos la reserva pasando el usuario, tabla, clave y PID con el UKI
0044    // unico
0045    //
0046    If VA frm_szReserversAplication_PID is equal to <Blank>
0047       F00095 Remove Business Object Reservation
              VA frm_UserId_USER -> BF szUserId
              "F55N42IC" -> BF szNameObject
              VA frm_GenericKey_GENKEY -> BF szGenericKey
              VA frm_szUniqueIDRecReserve_PID -> BF szApplication
0048    End If
0049    //


And This minimize the impact of multiple users to simultaneously work with the same document, it's very simple and we have avoid a lot of problems in the future!
And with this funcionality, minimaze the impact for edit some users in the same time

viernes, 1 de julio de 2016

[JD Edwards] Insert Javascript Code in Applications

In one of the latest projects, one of the requirements could easily be solved with JavaScript. But there was never inserted JavaScript code in an application of JD Edwards (I have not had this need).

I knew that it's possible insert HTML code in text blocks, but if you can add HTML code then you could embebed JavaScript!!

So, I was investigating and working in it, and I got add JavaScript in my JDE application!!!

Alert JavaScript from JD Edwards

In some post I read about for 8.90 and later versions you must enable security for it, but in my case I need with JD Edwards 9.2.

Code Example:

     evt_HTML_A030
     evt_iSegmentID_INT01
     evt_Message_ALPH
     evt_WebcenterContentLogin_URL
     OPT: Using Defaults
0001 //
0002 // Initialize Variables
0003 //
0004 VA evt_HTML_A030 = ""
0005 VA evt_iSegmentID_INT01 = 1
0006 //
0007 // Notify the tool that the Information text block contains encoded text.
0008 //
0009 Encode(FC Text Block 100, VA evt_HTML_A030, VA evt_HTML_A030)
0010 //
0011 // HTML & Javascript Code
0012 //
0013 //  
0014 VA evt_Message_ALPH = ""Hello JavaScript!!!""
0015 VA evt_HTML_A030 = concat([VA evt_HTML_A030],"<script type="text/javascript">")
0016 VA evt_HTML_A030 = concat([VA evt_HTML_A030],"function abrirVentana(){")
0017 VA evt_HTML_A030 = concat([VA evt_HTML_A030],"alert(")
0018 VA evt_HTML_A030 = concat([VA evt_HTML_A030],concat([VA evt_Message_ALPH],");"))
0019 VA evt_HTML_A030 = concat([VA evt_HTML_A030],"}")
0020 VA evt_HTML_A030 = concat([VA evt_HTML_A030],"</script>")
0021 VA evt_HTML_A030 = concat([VA evt_HTML_A030],"<button onclick="abrirVentana();">")
0022 VA evt_HTML_A030 = concat([VA evt_HTML_A030],"Alert</button>")
0023 VA evt_HTML_A030 = concat([VA evt_HTML_A030],"<script>")
0024 //
0025 // Add HTML & JS to segment
0026 //
0027 Add Segment(FC Text Block 100, VA evt_HTML_A030, <Default,Default,0,Default>, <No>, VA evt_iSegmentID_INT01)

The next steps will be create my own JavaScript library for separate and organize my JS code, and it allow will be more easier and faster to access JS functions.

Personally, I thint it opens up world of possibilities.

Welcome to Custom JD Edwards Applications, Javascript.

[JD Edwards] Insertar Javascript en Pantallas

En uno de los últimos proyectos realizados, una de las necesidades se podría resolver fácilmente con JavaScript. Pero nunca había insertado código javascript en una aplicación de JD Edwards (tampoco he tenido esa necesidad).

Lo que sí que sabía hasta el momento es que en los text blocks se podría insertar código HTML, pero si puedes insertar código HTML entonces se tenía que poder embeber código JavaScript!

Así que me puse a investigar y trabajar en ello, y pude añadir añadir Javascript!!!

Alert JavaScript from JD Edwards

En algunos post que leí comentan que para versiones superiores a 8.90 hay que habilitar seguridad para ello, en mi caso no fue necesario con JD Edwards 9.2.

Code Example:

     evt_HTML_A030
     evt_iSegmentID_INT01
     evt_Message_ALPH
     evt_WebcenterContentLogin_URL
     OPT: Using Defaults
0001 //
0002 // Initialize Variables
0003 //
0004 VA evt_HTML_A030 = ""
0005 VA evt_iSegmentID_INT01 = 1
0006 //
0007 // Notify the tool that the Information text block contains encoded text.
0008 //
0009 Encode(FC Text Block 100, VA evt_HTML_A030, VA evt_HTML_A030)
0010 //
0011 // HTML & Javascript Code
0012 //
0013 //  
0014 VA evt_Message_ALPH = ""Hello JavaScript!!!""
0015 VA evt_HTML_A030 = concat([VA evt_HTML_A030],"<script type="text/javascript">")
0016 VA evt_HTML_A030 = concat([VA evt_HTML_A030],"function abrirVentana(){")
0017 VA evt_HTML_A030 = concat([VA evt_HTML_A030],"alert(")
0018 VA evt_HTML_A030 = concat([VA evt_HTML_A030],concat([VA evt_Message_ALPH],");"))
0019 VA evt_HTML_A030 = concat([VA evt_HTML_A030],"}")
0020 VA evt_HTML_A030 = concat([VA evt_HTML_A030],"</script>")
0021 VA evt_HTML_A030 = concat([VA evt_HTML_A030],"<button onclick="abrirVentana();">")
0022 VA evt_HTML_A030 = concat([VA evt_HTML_A030],"Alert</button>")
0023 VA evt_HTML_A030 = concat([VA evt_HTML_A030],"<script>")
0024 //
0025 // Add HTML & JS to segment
0026 //
0027 Add Segment(FC Text Block 100, VA evt_HTML_A030, <Default,Default,0,Default>, <No>, VA evt_iSegmentID_INT01)

Los siguientes pasos será crear una librería JavaScript para tener el código por separado y que sea más sencillo y rápido poder acceder a las funciones JS.

Personalmente, creo que ésto abre un mundo de posibilidades.

Welcome to Custom JD Edwards, Javascript.

jueves, 2 de junio de 2016

[JD Edwards] Reserva de Objeto

Cuando un usuario está trabajando con un documento y lo está editando, deberíamos siempre no permitir que ningún otro usuario pueda modificarlo para no se produzca incongruencias. Ésto es lo que se conoce como Reserva de Objetos o Reserva de Documentos.

En JDE en la mayoría de pantallas estándar ésto está implementado, pero cuando creamos una pantalla custom deberíamos tenerlo en cuenta.

¿Cómo JDE realiza ésto?

Muy sencillo, lo que simplemente hace es cuando alguien se propone a editar un documento inserta un registro en la tabla F00095 y no lo elimina hasta que el usuario abandona la edición. De ésta manera, cuando otro usuario entra en otra instancia de la misma aplicación comprueba si existe el registro en la tabla F00095, de ser así muestra un error y bloquea para no permitir editar.

¿Qué hay que hacer?


Bien, entonces utilizando la función estándar "F00095 Reserve Object" con el UKID "RRESERVE", y normalmente con los valores claves del documento que estemos trabajando, ésta función realiza 2 cosas: por un lado comprueba si ya está reservado o no, y en caso de que no inserta el registro, o lo que es lo mismo lo reserva. En caso de que esté reservado, utilizamos la función "Set Object Reservation Text Substitution Error" para mostrar un error en la pantalla y además sería más deseable y más limpio que bloqueáramos todos los campos de la pantalla.

Ejemplo:


0080       //
0081       //  # Reserva #
0082       //
0083       // Cogemos un UKID (RRESERVE) de la F00022
0084       //
0085       Get Next Unique Key ID
              "RRESERVE" -> BF szObjectName
              VA frm_UniqueKeyIDInternal_UKID <- BF mnUniqueKeyID
0086       //
0087       // Lo convertimos a string para pasarselo a la función de reserva parámetro
0088       // PID
0089       //
0090       Math Numeric to String, Convert
              VA frm_UniqueKeyIDInternal_UKID -> BF mnMathNumeric01
              VA frm_szUniqueIDRecReserve_PID <- BF szVideoConstant30A
0091       //
0092       // Cogemos como clave el id de incidencia
0093       //
0094       VA frm_GenericKey_GENKEY = [FI mnIdentificadorIncidencia]
0095       //
0096       // Lo reservamos, pasándole usuario, clave, tabla, PID Único
0097       //
0098       F00095 Reserve Object
              "F55N42IC" -> BF szNameObject
              VA frm_UserId_USER -> BF szUserId
              "1" -> BF cSuppressErrorMessage
              VA frm_szRecordReserveErrMsg_DTAI <- BF szErrorMessageID
              VA frm_ReserversNameAlpha_ALPH <- BF szReserversNameAlpha
              VA frm_GenericKey_GENKEY -> BF szGenericKey
              VA frm_szUniqueIDRecReserve_PID -> BF szApplication
              VA frm_szReserversAplication_PID <- BF szReserversApplication
              "1" -> BF cWarningError
0099       //
0100       // Si está reservado, nos lo indicará en ErrorMesageID. Entonces mostramos
0101       // error y deshabilitamos el OK y los campos
0102       //
0103       If VA frm_szRecordReserveErrMsg_DTAI is not equal to <Blank> And VA frm_szRecordReserveErrMsg_DTAI is not equal to <Null>
0104          Set Object Reservation Text Substitution Error
                 VA frm_ReserversNameAlpha_ALPH -> BF szReserversNameAlpha
                 VA frm_GenericKey_GENKEY -> BF szGenericKey
                 VA frm_szReserversAplication_PID -> BF szApplication
                 "2" -> BF cWarningError
0105          Disable Control(HC &OK)
0106          Disable Control(FC 2nd Address Number)
0107          Disable Control(FC Address Book Name)
0108          Disable Control(FC Electronic Address)
0109          Disable Control(FC Phone Number)
0110          Disable Control(FC Fuente Incidencia)
0111          Disable Control(FC Motivo Incidencia)
0112          Disable Control(FC Estado Incidencia)
0113          Disable Control(FC Departamento Incidencia)
0114          Disable Control(FC Comment)
0115          Disable Control(FC Conclusión)
0116       End If

Por supuesto, una vez que finalicemos con la edición (cuando pulsemos el botón OK o Cancel normalmente), tenemos que quitar la reserva (el registro de la F00095) para que no se quede bloqueado y podamos editarlo a futuro mediante la BSFN "F00095 Remove Business Object Reservation".

Ejemplo:

0040    // # Quitamos la reserva
0041    //
0042    // Si la variable PID devuelta es blanco, es porque lo hemos reservado, por lo
0043    // tanto quitamos la reserva pasando el usuario, tabla, clave y PID con el UKI
0044    // unico
0045    //
0046    If VA frm_szReserversAplication_PID is equal to <Blank>
0047       F00095 Remove Business Object Reservation
              VA frm_UserId_USER -> BF szUserId
              "F55N42IC" -> BF szNameObject
              VA frm_GenericKey_GENKEY -> BF szGenericKey
              VA frm_szUniqueIDRecReserve_PID -> BF szApplication
0048    End If
0049    //


Y con ésto minimizamos el impacto de que varios usuarios a la vez trabajen con el mismo documento, algo muy simple y que nos puede evitar de bastantes problemas a futuro!

domingo, 22 de mayo de 2016

[JD Edwards] Show Clip Grid Attachment

When the row grid has attachment and we want show to the users, the most elegant is show a clip.

For it, the first step is desactivated check "Hide Row Headers" in grid properties:



The next step is use media object data structure of system function, and check with a flag and row keys of attachment if it has, and if it has will indicate to activate the clip else to desactivate.

Example:

0004 VA evt_MediaObject_EV01 = ""
0005 Media Object Structures(GT55NINC, <Default Media Object>, <Exist>, VA evt_MediaObject_EV01, GC Identificador Incidencia)
0006 If VA evt_MediaObject_EV01 is equal to "1"
0007    Set Grid Text Indicator(FC Grid, <Currently Selected Row>, <Yes>)
0008 Else
0009    Set Grid Text Indicator(FC Grid, <Currently Selected Row>, <No>)
0010 End If
0011 //

[JD Edwards] Mostrar Clip Anexos Grid

Cuando tenemos registros en un grid con anexos asociados y queremos mostrarlo al usuario, lo más elegante es mostrar el clip.

Para ello, primero tenemos que quitar el check de "Hide Row Headers" en las propiedades del grid:



Posteriormente, mediante la función de sistema de estructura del media object que estemos utilizando, comprobamos con un flag y con las claves de la fila si tiene media object, si lo tiene indicaremos que marque el indicador (clip) y sino que lo desactive:

0004 VA evt_MediaObject_EV01 = ""
0005 Media Object Structures(GT55NINC, <Default Media Object>, <Exist>, VA evt_MediaObject_EV01, GC Identificador Incidencia)
0006 If VA evt_MediaObject_EV01 is equal to "1"
0007    Set Grid Text Indicator(FC Grid, <Currently Selected Row>, <Yes>)
0008 Else
0009    Set Grid Text Indicator(FC Grid, <Currently Selected Row>, <No>)
0010 End If
0011 //

sábado, 21 de mayo de 2016

JD Edwards] JDEList - JDE Specialized Forum

All people who are dedicated to development, sooner rather than later we are doubts and problems. For this, we find manuals, tutoriales, but especially google where it leads to forums, blogs, videos, etc. For it, it's very important the technologie comunities, usually foro (like this), where we can ask and anser questions.

For JDEdwards, the best forum is JDEList where it is divide for categories (technical, applications and development) where in adittion the community provides third programs, etc.

JDEList Cover forum

If you go and find @alfredorz user greet him;)

[JD Edwards] JDEList - Foro Especializado JDE

Todos los que nos dedicamos al mundo del desarrollo, más pronto que tarde nos surgen dudas y problemas. Para ello, tiramos de manuales de cada tecnología, tutoriales, y sobre todo de google donde nos lleva a foros, blogs, vídeos, etc. Por ello es muy importante disponer de una comunidad de desarrolladores de la misma tecnología, habitualmente en foros, donde poder preguntar y resolver dudas.

Para JD Edwards el mejor foro sin duda que me he encontrado es JDEList, donde está dividido por categorías (técnicas, de aplicación y de desarrollo), donde además se aportan programas de terceros para facilitarnos las labores, etc.

JDEList Portada foro

Si pasáis y os encontráis con el usuario @alfredorz saludadle ;)

viernes, 13 de mayo de 2016

[JDE Edwards] JDETables - Web Referencia de Tablas

Tanto para los analistas funcionales como para los desarrolladores de JD Edwards es muy importante conocer las tablas con las que trabajamos y sus características: columnas, prefijos, campos, claves primarias, índices, etc. Y también es muy importante conocer los tipos de datos y sus características de cada columna (las definidas en el Diccionarios de Datos), así como las relaciones de las tabla.

E incluso para los que desarrollamos, es muy útil conocer la posición de cada columna en la tabla cuando tenemos que hacer alguna operación (fetch single, select, fetch next, update, etc) - sobre todo con tablas formadas por muchas columnas.-

Yo vengo utilizando para ello desde hace bastante tiempo una página web muy útil llamada JDETables:


Nos permite buscar las tablas en las distintas versiones de JDE (actualmente 8.12, 9.10 y 9.12), y nos detalla todas las características tales como las columnas que compone la tabla (con el alias, descripción, tipo de dato, etc), prefijo, clave primaria, índices, código de sistema al que pertenece, descripción de la tabla, número de columnas e índices, etc. E incluso nos permite construir sentencias SQL (select, update e insert).





Podemos ver todas las tablas de cada código de sistema, las tablas más consultadas, todas las tablas que utilizan un campo cuando clickamos en él, etc.


Y además es gratuita y no es necesario registrarse.


¡Una herramienta imprescindible para nuestro día a día!