viernes, 23 de diciembre de 2016

[JD Edwards] Tools 9.2.1 - Forms Personalitation

In new JD Edwards 9.2.1 tools, a new feature is Personal Forms. This feature allow customize forms to end user, as they could customize grid. It allow show or hide fields, move fields, resize fields,... on runtime. In the next video you can watch posibilites:


It's very powerfull tool, this will allow to developers and users be more productive.

Enable feature in system:

To enable this feature you have to activate it in UDO's, you can see this official document.

Go to Security Workbench P00950 -> Form -> Feature Security, find "PERSFORM" and enable access:

Later you go to UDO's page and enable for users:
In P00950 -> Form -> User Defined Object -> Action. Click in Add: Fill fields

You need clear the jdbj security cache in Server Manager and reset session to see this feature enabled.


Works with Personal Forms:

In any form, you can see Personal Form icon on top right:



Click and you can start to personalize your form:



If you click on less icon, the field hided and it'll appear in right panel for if you want show later. you can move fields, resize, change labels, etc.

For more information you can access this official document.

miércoles, 12 de octubre de 2016

[Javascript] Función filter

Hola amigos,

Después de probar el  ejemplo de filtro Javascript de nuestros amigos DevCode he decidio optimizarlo con la función filter javascript para arreglos o arrays.

La sintaxis es:

array.filter(function(element){return condicion_cumplir_elemento});

Ejemplo:

index.html
<!DOCTYPE html>
<html lang="es">
<head>
<title>Buscador Javascript</title>
<meta charset="utf-8"/>
<script type="text/javascript" src="source.js"></script>
</head>
<body>
<input type="text" id="buscar-pal" onkeyup="autocompletado2()" style="border: solid 2px" />
<div>
<ul id="demo"></ul>
</div>

</body>
</html>

source.js
function autocompletado2(){
document.getElementById("demo").innerHTML='';

var preguntas = [
"BASIC",
"C",
"C++",
"Java",
"Javascript",
"PHP",
"Python",
"Ruby"
];

var pal = document.getElementById("buscar-pal").value;
var tam = pal.length;
if(tam>0){
var filtrados = preguntas.filter(function(nombre){
var nombrelower = nombre.toLowerCase();
return nombrelower.indexOf(pal.toLowerCase()) != -1;
}
);
for(indice in filtrados){
var node = document.createElement("li");
var textnode = document.createTextNode(filtrados[indice]);
node.appendChild(textnode);
document.getElementById("demo").appendChild(node);
}
}
}

El resultado:




[Javascript] filter Function

Hi friends,

After testing Javascript filter sample of our friend DevCode () I've decided to optimize with javascript filter function for arrays.

The syntax it's:

array.filter(function(element){return condition_for_element});

Example:

index.html
<!DOCTYPE html>
<html lang="es">
<head>
<title>Buscador Javascript</title>
<meta charset="utf-8"/>
<script type="text/javascript" src="source.js"></script>
</head>
<body>
<input type="text" id="buscar-pal" onkeyup="autocompletado2()" style="border: solid 2px" />
<div>
<ul id="demo"></ul>
</div>

</body>
</html>

source.js
function autocompletado2(){
document.getElementById("demo").innerHTML='';

var preguntas = [
"BASIC",
"C",
"C++",
"Java",
"Javascript",
"PHP",
"Python",
"Ruby"
];

var pal = document.getElementById("buscar-pal").value;
var tam = pal.length;
if(tam>0){
var filtrados = preguntas.filter(function(nombre){
var nombrelower = nombre.toLowerCase();
return nombrelower.indexOf(pal.toLowerCase()) != -1;
}
);
for(indice in filtrados){
var node = document.createElement("li");
var textnode = document.createTextNode(filtrados[indice]);
node.appendChild(textnode);
document.getElementById("demo").appendChild(node);
}
}
}

The result:




lunes, 12 de septiembre de 2016

[OracleJET] Introducing to Oracle JET

Hi friends, I'm back from holidays, and I'll try write more posts regullary.

In the last 3 weeks I did a Oracle MOOC of Oracle JET. Oracle JET it's a new Oracle Tool, released on November 2015, based in Javascript. According Oracle, not is a Javascript framework else a collection of javascript libraries and technologies to build enterprise client-side applications.



Oracle JET is compose for libraries as: RequireJS, Knockout, JQuery, JQueryUI, Cordova.



Go to official Oracle JET web: http://www.oracle.com/webfolder/technetwork/jet/index.html

You can create web applications and mobile applications (or both).

Oracle JET use AltaUI Style and has a lot of components. In Oracle JET Cookbook site you can see all components, properties and you can test, it's a very useful page: http://www.oracle.com/webfolder/technetwork/jet/jetCookbook.html



As client-side (you should know something of HTML, JS and CSS) application communicate with webservices: REST and JSON, preferably Oracle Cloud Services.

The IDE for work it's Netbeans (I worked with this IDE for JAVA projects and I like). Of course you can use console to create and build application with yeoman.

The next Oracle JET MOOC it's the next 3th October. For more information and enroll: https://blogs.oracle.com/javatraining/entry/announcing_a_second_session_of




miércoles, 24 de agosto de 2016

[MAF] MAF 2.3.2 Release

The new version 2.3.2 has been  released. Has important changes to iOS platform and other features:

- WKView Support for iOS
- Support for IPv6 only networks on iOS
- Single Sign-On in MCS and other PaaS
- Templates Layout for new AMX pages
- New components: Dotted Page Control and Picto chart
- Clear text attribute for all input text.
- geographicMap can now use Oracle Maps Cloud Service for routes
- And more.

You can see more information about it in the next links:

https://blogs.oracle.com/mobile/entry/oracle_maf_2_3_2

http://docs.oracle.com/middleware/maf232/mobile/develop-maf/GUID-4C5D7100-DFA8-44E6-911C-F40280E679D9.htm#ADFMF24915

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 ;)

lunes, 16 de mayo de 2016

[Oracle ADF] Faces Rich Client - Component Tests

One of the great potential of Oracle ADF is the large number of standard components that the framework provides. In addition, many of these components can combine to create a more customized.

Until now, to try each one of these components and see their chances we had create a demo application in local and test each component.

With ADF Faces Rich Client & nbsp; Oracle has created an online website where you can go see and test each of the components (in addition it are classified), it gives us a brief explanation of each of them and even allows us to change some property. 





In addition, it allow us change styles, see ADF page code, etc.


Go to test!!!

[Oracle ADF] Faces Rich Client - Prueba Componentes

Uno de los grandes potenciales de Oracle ADF es la gran cantidad de componentes estándar que el framework nos proporciona. Además, muchos de esos componentes podemos combinarlos para crear uno más customizado.

Hasta ahora, para ir probando cada uno de éstos componentes y ver sus posibilidades no nos quedaba otra que crear una aplicación demo en local e ir trabajando con cada uno de ellos.

Con la página ADF Faces Rich Client  que Oracle ha creado un página web online donde podemos ir viendo cada uno de los componentes (además para facilitarnos están clasificados), nos da una explicación breve de cada uno de ellos e incluso nos permite cambiar alguna propiedad. 

Podemos acceder a ella en el siguiente enlace: http://jdevadf.oracle.com/adf-richclient-demo/faces/index.jspx




Además, nos permite cambiar los estilos, ver el código ADF de la página, etc!


A probar!!!

[Oracle MAF] CompGalleryDemo 2.2 - Prueba Componentes

Cuando trabajamos con un framework, debemos saber los componentes estándar de los que éste dispone y testearlos para ver las posibilidades que nos ofrece.

Para MAF, cuando instalamos la extensión nos descarga una serie de ejemplos en ruta_instalacion\jdev\extensions\oracle.maf\Samples\PublicSamples.zip donde descomprimimos y podemos ver cómo están construidas las aplicaciones. Entre ellas se encuentra el 'CompGallery' donde después de compilar y desplegar en nuestro dispositivo o en uno virtual podemos ver, probar e incluso cambiar ciertas propiedades de cada componente.

Ésto es muy útil ya que nos permite de una manera visual, limpia y rápida poder ver las capacidades de cada componente.

Pero además, también podemos probarlas en nuestro navegador web gracias a la aplicación web creada por oracle en la siguiente dirección http://jdevadf.oracle.com/amx/CompGalleryDemo











Así que a probar!!!!

domingo, 15 de mayo de 2016

[Oracle MAF] CompGalleryDemo 2.2 - Components Test

When we working with a framework, we must know the standard components available to it and test them to see possibilities it offers

In MAF, when we installed the extension it downloaded examples on installation_path\jdev\extensions\oracle.maf\Samples\PublicSamples.zip when we descompressed and we can see how applications are built. A application is 'CompGallery' where next to buid and deploy in our mobile phone or virtual phone, we ca see, test and even change components properties.

It's very useful because it allow us a visual, clean and easy way to see the compoments capabilities.

In addition, also we can try in our explorer web using the web application created by Oracle at the following address http://jdevadf.oracle.com/amx/CompGalleryDemo











So go to try!!!!

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!





[JDE Edwards] JDETables - Reference Web Tables

For JD Edwards functional analysts and development is very important to know the tables we work and characterists: columns, prefixes, indexes, primary key, etc. And also it's very important to know data types and column characterists (defined in Data Dictionary) and tables relationship.

And even for developers, it's very useful to know column position when we have doing some operation (fetch single, select, fetch next, update, etc.) - especially for tables that it have many columns-

I have being using to it for quite some time a very useful website called JDETables:



It allow us to find the tables in the differents JDE versiones (currently 8.12, 9.10 and 9.12) and it detailed all the features such as table columns (with the alias, description, data type, etc.), prefix, indexes, primary key, system code, table description, columns number and indexes, etc. And even it allow us to build SQL sentences (select, update and insert).




We can see all tables for code system, more queried tables, all tables used by a field, etc.



And it's free and not it doesn't need register.


An essential tool for our day to day!!!


jueves, 5 de mayo de 2016

[JD Edwards] Execute Windows / Linux Commands


Sometimes we are in a situation where in JDE not have a function, features or functionality to perform a certain task, or is too complex, and with a Windows command or Linux command (depends of Enterprise Server) it's easy. For example search text files in a directory, search for a PDF generated with BIP, etc.


In JDE through the Business Fuction "Execute External Program" (B34A1030) we can execute these commands. I can even make a script (.bat in Windows or .sh in Linux)



Example:

//
// Linux command to search files
//
VA evt_Command_NFLF = concat('/bin/ls -1 ',concat(directory,concat(' | egrep -i $*.csv > ',tempFile_directory)))
//
// Windows command to search files
//
VA evt_Command_NFLF = concat('dir /A:-D /B ',concat(directory,concat(' > ',tempFile_directory)))
//
Execute External Program
VA rpt_ErrorCode_ERRC <- BF cErrorCode
VA evt_Command_NFLF -> BF szCommandLine
//
If VA rpt_ErrorCode_ERRC is equal to "1"
   Stop Batch Processing
End If
//

[JD Edwards] Ejecutar Comandos Windows / Linux



En algunas ocasiones nos encontramos en una situación en la cual en JDE no tenemos una función, funciones o funcionalidad para realizar una determinada tarea, o es demasiado complejo, y con un comando de Windows o Linux (ésto dependerá del servidor Enterprise) nos resultaría más sencillo. Por ejemplo, para buscar archivos de texto en un directorio, buscar un PDF generado con BIP, etc.



Pues bien, en JDE a través de la Business Function "Execute External Program" (B34A1030) podemos ejecutar dichos comandos. He incluso podemos realizar un script (.bat en Windows o .sh en Linux).


Ejemplo práctico:


// Comando Linux para buscar fichero
VA evt_Comando_NFLF = concat('/bin/ls -1 ',concat(directorio,concat(' | egrep -i $*.csv > ',fichTermporal_directorio)))

// Comando Windows (excluimos directorios /A:-D)
VA evt_Comando_NFLF = concat('dir /A:-D /B ',concat(directorio,concat(' > ',fichTermporal_directorio)))
Execute External Program
        VA rpt_ErrorCode_ERRC <- BF cErrorCode
        VA evt_Comando_NFLF -> BF szCommandLine
If VA rpt_ErrorCode_ERRC is equal to "1"
   Stop Batch Processing
End If

miércoles, 4 de mayo de 2016

[JD Edwards] Loop Selected Rows Grid

In the previously post we saw about loop all rows on grid.

In this post we're going see how loop selected grid rows when we have it set to "Multiple Select". It's very useful for example when we want see in a FC field the amount summatory of grid, or when we want process the selected lines in other form, or when we want process selected lines in a report, etc.

We need the next system functions:

Get Selected Grid Row Count(FC Grid, VA frm_SelectedCount_LNID) -> get total selected rows

Get Selected Grid Row Number(FC Grid, VA frm_GridRowNumber_INT01) -> get the first row selected

Get Grid Row(FC Grid, VA frm_GridRowNumber_INT01) -> get the row id value into GC

Get Next Selected Row(FC Grid, VA frm_GridRowNumber_INT01, VA frm_GridRowNumber_INT01) -> get the next selected row

For doing it, we get the total rows selected, if it's greater than 0, get the first row, get the GC values, process row and get the next selected row in a loop.





Example:

VA frm_55_CurrentRow_MATH01 = 1
Get Max Grid Rows(FC Grid, VA frm_55_TotalRows_MATH01)
If VA frm_55_TotalRows_MATH01 is not equal to <Zero>
While VA frm_55_CurrentRow_MATH01 is less than or equal to VA frm_55_TotalRows_MATH01
Get Grid Row(FC Grid, VA frm_55_CurrentRow_MATH01)
//
// Works with row
//
GC CatCod1 = FC CatCod1
//
F4211.Update
GC Order Co = TK Order Company (Order Number)
GC Order Number = TK Document (Order No, Invoice, etc.)
GC Or Ty = TK Order Type
GC Line Number = TK Line Number
VA frm_55_SecuencialFiltro_JOBN -> TK Work Station ID
//
VA frm_55_CurrentRow_MATH01 = [VA frm_55_CurrentRow_MATH01]+1
End While
End If

[JD Edwards] Recorrer Líneas Seleccionadas Grid

En el anterior post vimos cómo recorrer todas las líneas del grid.

En ésta ocasión veremos cómo recorrernos sólo las líneas seleccionadas del grid cuando lo tenemos configurado como "Multiple Select". Ésto es muy práctico cuando por ejemplo queremos en un campo FC queremos visualizar el sumatorio del importe de las líneas seleccionadas, cuando queremos seleccionar las líneas para procesarlas en una segunda pantalla, cuando queremos filtrar las líneas seleccionadas en un informe, etc.

Para ello, necesitaremos usar las siguientes funciones de sistema:

Get Selected Grid Row Count(FC Grid, VA frm_SelectedCount_LNID) -> Obtenemos el número total de líenas seleccionadas en el segundo parámetro del grid indicado en el primer parámetro.

Get Selected Grid Row Number(FC Grid, VA frm_GridRowNumber_INT01) -> Nos devuelve en la variable del segundo parámetro el id de la primera línea seleccionada.

Get Grid Row(FC Grid, VA frm_GridRowNumber_INT01) -> Nos devuelve en GC el valor de la fila indicada en el segundo parámetro.

Get Next Selected Row(FC Grid, VA frm_GridRowNumber_INT01, VA frm_GridRowNumber_INT01) -> Nos devuelve en la variable del segundo parámetro el id de la siguiente línea seleccionada.


Para ello, obtenemos el nº total de líneas seleccionas y si es mayor de 0, es decir, hay líneas seleccionadas, obtenemos la primera línea e iteramos sobre el resto de líneas seleccionadas mientras haya en un bucle.



Ejemplo práctico:

//
//Obtiene el nº de líneas seleccionadas
//
Get Selected Grid Row Count(FC Grid, VA frm_SelectedCount_LNID)
//
//Si hay seleccionadas se procesan
//
If VA frm_SelectedCount_LNID is greater than Zero
  //
  //Obtiene el nº de la 1ª línea seleccionada
  //
  Get Selected Grid Row Number(FC Grid, VA frm_GridRowNumber_INT01)
  //
  //Mientras haya seleccionadas procesamos.
  //
  While VA frm_GridRowNumber_INT01 is greater than Zero
    //
    //Obtiene los valores de la línea - en GC
    //
    Get Grid Row(FC Grid, VA frm_GridRowNumber_INT01)
    //
    //Obtiene la siguiente línea seleccionada
    //
    Get Next Selected Row(FC Grid, VA frm_GridRowNumber_INT01, VA frm_GridRowNumber_INT01)
  End While
End If

martes, 3 de mayo de 2016

[JD Edwards] Loop All Grid Rows

A lot of times we'll need looping all grid rows, for example, for update a grid column, save the rows in a auxiliar table, etc. It's easy if we use system functions:

Get Max Grid Rows(FC Grid, Total_Rows) -> This system function returns total grid rows in the second parameter for the grid indicated as the first parameter.

Get Grid Row(FC Grid, RowId) -> This system function returns the GC values for the line id number indicated as the second parameter.


And with this functions, we'll doing a loop to iterate above all rows, and a variable for current row where we initialized to 1 and increase by 1 on each iteration (previously checking that there are lines in grid)






Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
VA frm_55_CurrentRow_MATH01 = 1
Get Max Grid Rows(FC Grid, VA frm_55_TotalRows_MATH01)
If VA frm_55_TotalRows_MATH01 is not equal to <Zero>
While VA frm_55_CurrentRow_MATH01 is less than or equal to VA frm_55_TotalRows_MATH01
  Get Grid Row(FC Grid, VA frm_55_CurrentRow_MATH01)
  //
  // Works with row
  //
  GC CatCod1 = FC CatCod1
  //
  F4211.Update
  GC Order Co = TK Order Company (Order Number)
  GC Order Number = TK Document (Order No, Invoice, etc.)
  GC Or Ty = TK Order Type
  GC Line Number = TK Line Number
  VA frm_55_SecuencialFiltro_JOBN -> TK Work Station ID
  //
  VA frm_55_CurrentRow_MATH01 = [VA frm_55_CurrentRow_MATH01]+1
 End While
End If

[JD Edwards] Recorrer Líneas Grid

En numerosas ocasiones nos encontraremos con la necesidad de recorrer todas las líneas del grid, por ejemplo para actualizar el valor de una columna, guardar las líneas en una tabla auxiliar, etc. Ésto es sencillo si utilizamos las funciones del sistema de Grid:

Get Max Grid Rows(FC Grid, Total_Rows) -> Ésta system function nos devuelve en el segundo parámetro el número total de líneas del grid indicado en el primer parámetro.

Get Grid Row(FC Grid, RowId) -> Ésta system function nos devuelve en las GC el número de línea indicado como segundo parámetro.

Y con éstas funciones, un bucle para iterar sobre todas las líneas y una variable donde llevemos la línea actual comenzando en la línea 1 e incrementando en 1 en cada iteracción lo tendremos hecho (comprobando previamente que existen líneas en el grid).



Ejemplo práctico:

VA frm_55_LineaActual_MATH01 = 1
Get Max Grid Rows(FC Grid, VA frm_55_TotalLineas_MATH01)
If VA frm_55_TotalLineas_MATH01 is not equal to <Zero>
   While VA frm_55_LineaActual_MATH01 is less than or equal to VA frm_55_TotalLineas_MATH01
      Get Grid Row(FC Grid, VA frm_55_LineaActual_MATH01)
      //
      //  Operaciones a realizar con la línea
      //
       GC CatCod1 = FC CatCod1
      //
      F4211.Update
         GC Order Co =  TK Order Company (Order Number)
         GC Order Number =  TK Document (Order No, Invoice, etc.)
         GC Or Ty =  TK Order Type
         GC Line Number =  TK Line Number
         VA frm_55_SecuencialFiltro_JOBN -> TK Work Station ID
      //
      VA frm_55_LineaActual_MATH01 = [VA frm_55_LineaActual_MATH01]+1
   End While
End If