Migración de código a extensiones, Dynamics NAV a Business Central

0
49

Tradicionalmente, al pasar de una versión a otra del antiguo Dynamics NAV uno tenía que hacer una comparación entre el código estándar de su versión y su código modificado para saber, fehacientemente, qué había sido modificado y modificarlo para obtener el mismo resultado en la nueva versión de destino de Dynamics NAV.

Este hecho, el tener que pasar todo el código de una forma eminentemente manual, acrecentaba mucho los costes asociados a largo plazo de la implantación de Dynamics NAV (Manual sobre todo a raiz de la refactorización que comenzó con NAV2018). A los costes de los desarrollos en origen se sumaba el proceso de cambiar los desarrollos de una versión a otra (Recordando que de NAV 5 a cualquier versión de Dynamics NAV los formularios se debían convertir de forma totalmente manual a páginas, por ejemplo, o los informes el layout).

De este modo, llegaron las extensiones. Básicamente, en Dynamics NAV tu podías modificar el comportamiento del programa en cualquier punto del mismo, podías eliminar todo el comportamiento estándar del programa sin ningún tipo de problema. Ahora, con las extensiones, es Microsoft el que te ha dejado puntos en el código de programa, en el que puedes realizar modificaciones. Sigues teniendo la potestad de cambiar comportamientos estándar, ampliar funcionalidades y crear nuevas funcionalidades pero en los puntos de los procesos en los que Microsoft te permita.
Ejemplo muy tonto:

Esta forma nueva de modificar el programa permite que ya no tengas que comparar todo el código para pasar a la nueva versión sino que solo tengas que revisar si el código en la nueva versión falla y, solo en ese caso, modificarlo. Apriorísticamente el 99% del código, salvo modificación importante de Microsoft, no requerirá revisión alguna. (Como ejemplo, un desarrollo típico en España como es el nombre del cliente/proveedor en cartera no ha dado problemas en los últimos 4 años y no se ha tenido que hacer nada con el a pesar que la nube se ha ido actualizando mes a mes)

Para realizar el cambio a extensiones de forma sencilla es necesario encontrarte con todo migrado en la ultima versión con C/AL, Business Central 14 o «2019 Spring». Esto es necesario porque en dicha versión se agregó la opción de exportar los objetos para una nueva sintaxis de forma que se automatizase buena parte del proceso de migración.

1º Exportar los objetos de nuestra base de datos BC14 con nueva sintaxis.

NAV Development Shell:

Export-NAVApplicationObject -DatabaseServer DBServer\SQLInstance -DatabaseName "MiBBDD" -ExportToNewSyntax -Path "c:\export2al\Modificados\modificadosbc14app-part1.txt" -Filter 'Id=1..129999' -ExportTxtSkipUnlicensed

Export-NAVApplicationObject -DatabaseServer DBServer\SQLInstance -DatabaseName "MiBBDD" -ExportToNewSyntax -Path "c:\export2al\Modificados\modificadosbc14app-part2.txt" -Filter 'Id=140000..1999999999' -ExportTxtSkipUnlicensed

2º Exportar los objetos de una base de datos sin modificar de BC14. (La misma CU que nuestra base de datos)

NAV Development Shell:

Export-NAVApplicationObject -DatabaseServer DBServer\SQLInstance -DatabaseName "CRONUS" -ExportToNewSyntax -Path "c:\export2al\Originales\originalesbc14app-part1.txt" -Filter 'Id=1..129999' -ExportTxtSkipUnlicensed

Export-NAVApplicationObject -DatabaseServer DBServer\SQLInstance -DatabaseName "CRONUS" -ExportToNewSyntax -Path "c:\export2al\Originales\originalesbc14app-part2.txt" -Filter 'Id=140000..1999999999' -ExportTxtSkipUnlicensed

3º Comparar unos archivos con otros. La realidad es que cada diferencia que encontremos tiene que ser, por necesidad, una modificación del código estándar. Esta comparación generará unos ficheritos que aglutinarán esas diferencias.

NAV Development Shell:

Compare-NAVApplicationObject -OriginalPath "c:\export2al\Originales\" -ModifiedPath "c:\export2al\Modificados\" -DeltaPath "C:\export2al\Delta\" -ExportToNewSyntax

4º Convertir en AL esas diferencias de forma que si son tablas nuevas genere tablas, si son campos nuevos en una tabla estándar genere una TableExtension y lo mismo con páginas. No hará el traspaso a AL ni de codeunits ni de reports, eso tendremos que hacerlo a mano y/o generarlos tal cual están en AL (Ver nota al final). Los ficheros deltas servirán, en el caso de las codeunits, para ver qué codigo es nuevo pero la suscripción a eventos en AL será una tarea manual.

CMD de windows (Con administrador)

cd C:\Program Files (x86)\Microsoft Dynamics 365 Business Central\140\RoleTailored Client

txt2al --source="C:\export2al\Delta" --target="C:\export2al\AL" --injectDotNetAddIns --dotNetTypePrefix=BC --rename

Ahora en la carpeta «AL» tendremos los ficheros que se corresponden con los objetos 50k, las pageextensions y las tableextensions correspondientes a modificaciones en objetos estándar.
Las modificaciones a codeunits y reports del estándar tendrán que hacerse de forma totalmente manual.

Podríamos haber excluido de la comparación los objetos 50k ya que estos podrían exportarse y convertirse en AL directamente. (Es decir, hacer el punto 1 y el 4 con dichos objetos filtrando en el punto 1 por el -Filter ‘Id=50000..99999’)

En este punto, pues, es donde entra el proceso mas laborioso y eminentemente manual dado que:

  • Las TableExtensions y PageExtensions pueden contener cambios de código que haya que realizar manualmente mediante suscripción a eventos o cambiarlos de lugar. Algunos cambios de propiedades en campos estándar pueden no ser realizables en AL.
  • Las Codeunits, sabremos las diferencias si vamos a los ficheros de los deltas, en la carpeta Delta. Mediante esas diferencias habrá que buscar el evento al que se debe suscribir para conservar la funcionalidad.
  • Los reports se realizarán mediante reportextensions o podemos duplicarlos y sustituir los estándar. No óbice, habrá que comprobar el funcionamiento.
  • Los objetos 50k el cambio es directo y no tienen por qué ser revisados.

Así pues tenemos buen trabajo por delante hecho porque, por un lado tenemos objetos generados ya y, por otro, tenemos unos ficheros que nos indican las diferencias entre el código estándar y el modificado, no dependemos de comentarios de los buenos desarrolladores.

No obstante, tenemos mucho tiempo por delante ya que todo código estándar modificado habrá que rehacerlo suscribiéndose a eventos de los objetos estándar. Está bien saber que, en el horizonte, esta es la última vez que tendremos que realizar esta tarea pero, por el momento, la tarea no es sencilla y más con toda la refactorización que se ha producido en toda la aplicación.

Esta migración va a ser muy costosa, de NAV2016 a BC14 C/AL, el coste de la migración es de entre 3 a 5 veces menor que el coste de BC14 C/AL a BC14 AL en tiempo, por ejemplo, pero el costo de BC14 AL a BC22 AL es realmente exiguo.

Como nota, una migración de BC14 C/AL a BC22, requiere de tener las extensiones en BC22, no hay que hacerlas dos veces, no hay que hacer dos revisiones de datos y menos de funcionalidad. Esto lo veremos en la siguiente entrada.

Si la migración me planteasen hacerla de 2016 a BC22, por ejemplo, convertiría a BC14 (es decir instalar la BBDD y abrirla con el development environment de BC14) tanto mi BBDD como la Cronus de la versión de 2016 la CU que corresponda. Una vez en ese punto, haría los pasos anteriores sabiendo que pueden dar algunos errores mas, por cambios de nombres y demás en las PageExtensions sobre todo.

También podría hacerse con los siguientes pasos tradicionales con los que obtendríamos en C/AL todo para ponerlo en BC14 y entonces comenzaríamos con los del inicio de la entrada.

NAV2016 Cronus
Export-NAVApplicationObject –DatabaseServer DESKTOP-LOJLSD5\POWERBI –DatabaseName "Demo Database NAV (9-0)" –Path C:\Merge\CronusNAV16\Cronus16.txt -Filter 'Id=1..1999999999'

MiBBDD2016
Export-NAVApplicationObject –DatabaseServer DESKTOP-LOJLSD5\POWERBI –DatabaseName "miBBDD" –Path C:\Merge\MiBBDD2016\MiBBDD2016.txt -Filter 'Id=1..1999999999'

BC14Cronus (Se haria la exportación instalando BC14)
Export-NAVApplicationObject –DatabaseServer DESKTOP-LOJLSD5\POWERBI –DatabaseName "BC14Cronus" –Path C:\Merge\CronusBC14\CronusBC14.txt -Filter 'Id=1..1999999999'


NAV2016 Cronus
Split-NAVApplicationObjectFile -Source C:\Merge\CronusNAV16\Cronus16.txt -Destination C:\Merge\CronusNAV16\Splited\

MiBBDD2016
Split-NAVApplicationObjectFile -Source C:\Merge\MiBBDD2016\MiBBDD2016.txt -Destination C:\Merge\MiBBDD2016\Splited\

BC14Cronus
Split-NAVApplicationObjectFile -Source C:\Merge\CronusBC14\CronusBC14.txt -Destination C:\Merge\CronusBC14\Splited\


Generación Deltas
Compare-NAVApplicationObject -DeltaPath C:\Merge\Deltas16 -ModifiedPath C:\Merge\MiBBDD2016\Splited\ -OriginalPath C:\Merge\CronusNAV16\Splited\

Merge de todo

Merge-NAVApplicationObject -ModifiedPath C:\Merge\MiBBDD2016\Splited\ -OriginalPath C:\Merge\CronusNAV16\Splited\ -TargetPath C:\Merge\CronusBC14\Splited -ResultPath C:\Merge\Result\

La verdad es que no se cual de las dos opciones es mejor, yo utilicé tan solo la segunda, es decir, comparar las tres versiones y luego ya lanzarme a sacar en AL los objetos.

Como se relató anteriormente, el cambio de C/AL a AL, es decir de NAV a BC principalmente, es un cambio complejo. Aunque estas herramientas te facilitan la obtención del resultado el arduo trabajo de desarrollo tiene que llevarse a cabo manualmente.
Ya no es poner el código en el mismo lugar de la Codeunit haciendo, por ejemplo, que al registrar un pedido solo pueda registrarse el envío, ahora habrá que rediseñarlo completamente de forma que la Codeunit del estándar no se ejecutará (suscribiéndose a un evento que permite determinarlo) de forma que se ejecutará una nueva Codeunit con ese código cambiado, por ejemplo.