Dentro del mundo de desarrollo de aplicaciones hay varias fases importantes, da igual la metodología que apliquemos, sea Waterfall, Agile, SAP Activate o cualquiera. Siempre hay que Analizar el requerimiento, proponer soluciones, implementarlas y finalmente probarlas para validarlas y ponerlas en producción.
Vamos a ver el trabajo que se tiene que hacer por parte de los testers, probadores o validadores de la calidad del producto entregado. Veremos que hay varias capas de equipos de pruebas para asegurar la calidad final y cual es la labor de cada uno de ellos.
Eeeeeh, no, no me refiero a estos «probadores»
Por un lado tenemos los equipos de Calidad, QA y QC, por otro lado tenemos las pruebas de aceptación de usuario, las UATs. Y he dicho QA/QC pero eso no es un grupo de rock australiano. Se trata de dos siglas de dos equipos de trabajo en proyectos, ya sean de consultoría o de fabricación de batamantas.
QA – Quality Assurance
QC – Quality Control
Hard as a rock
Si bien se confunden entre sí, son dos equipos con tareas y objetivos distintos. Vamos a verlos.
¿Qué es Quality Assurance (QA)?
El Quality Assurance (QA) es básicamente un conjunto de acciones planificadas que se implementan durante el desarrollo de un producto, especialmente en software, para asegurar que todo funcione como debería antes de que llegue a las manos del cliente. ¿Cómo lo hace? Revisando y mejorando los procesos en cada fase: desde que se planea y diseña el producto, hasta su desarrollo, pruebas y despliegue. De esta manera, se minimizan los errores y se garantiza que el producto cumpla con los estándares de calidad esperados. Por lo general, en proyectos de tipo Waterfall, donde las fases son secuenciales y están muy delimitadas, se hace más énfasis es en la fase de pruebas.
De hecho en la mayoría de proyectos donde existe un equipo de QA, este se circunscribe únicamente a probar el software, eso sí, con la visión de control de errores, experiencia de usuario (UX) y pruebas de ciclo completo de integración entre sistemas. Lo cual hace que hay un equipo denominado de QA que realmente esté haciendo labores de Quality Control (QC).
¿Qué es Quality Control (QC)?
Quality Control (QC) es el proceso mediante el cual se revisa y evalúa el producto final para asegurar que cumpla con los requisitos de calidad establecidos.
El objetivo principal del QC es identificar cualquier fallo o discrepancia en el producto antes de que llegue al cliente, lo cual se logra mediante diversas pruebas, inspecciones y evaluaciones. Estas revisiones pueden incluir desde pruebas funcionales hasta revisiones visuales y de rendimiento. Si se encuentran problemas, estos se corrigen antes de lanzar el producto al mercado.
En resumen, QC se asegura de que el producto que se entrega al cliente final sea de alta calidad, revisando el resultado después de que todas las fases de desarrollo han sido completadas.
Diferencia entre Quality Assurance (QA) y Quality Control (QC)
Aunque suenan parecidos, Quality Assurance (QA) y Quality Control (QC) no son lo mismo. QA se encarga de que todo vaya bien desde el principio: se preocupa de que el proceso de desarrollo sea sólido para evitar que haya errores. QC, por otro lado, entra en acción cuando el producto ya está listo y se centra en revisar si hay problemas o defectos que se escaparon. Piensa en QA como el entrenador que te prepara para evitar errores, mientras que QC es el árbitro que señala los fallos cuando ya está todo en juego. QA trata sobre el proceso, y QC, sobre el resultado final.
No obstante, dentro de uno hay un poco del otro y viceversa, como el yin y el yang de la gestión de calidad. Pero cada uno tiene un objetivo marcado. Aunque en ocasiones no sepamos llamar a las cosas por su nombre.
¿Qué son las UAT – User Acceptance Testing?
Las UAT (User Acceptance Testing), o pruebas de aceptación de usuario, son un tipo específico de pruebas realizadas al final del ciclo de desarrollo de software que se realizan para validar que el producto cumple con los requisitos y expectativas del usuario final o del cliente. Es el último paso antes de que el producto se implemente o se lance oficialmente.
Para mi es imprescindible que el cliente tenga perfiles especializados que hagan de enlace entre el negocio, sus peticiones de desarrollo de software y el equipo implementador. Es necesario que estos usuarios expertos sepan cómo funciona el negocio, las expectativas y cómo funciona la tecnología a aplicar. Sin estas pruebas no debe pasarse nada a producción.
En conclusión
Como hemos dicho con la metáfora del yin yang, QA y QC comparten algunas tareas, lo mismo pasa en las pruebas (de integración, UATs, etc.). Las tareas de pruebas de calidad de QC también pueden realizar se en QA y las pruebas de validación de usuario UAT son parte del control de calidad del resultado final.
Esto no se ha hecho con IA, se ha hecho con WordArt. A veces menos es mejor.
En un mundo ideal todo esto tendría que ser tal y cómo lo hemos explicado, tendría que haber un equipo de QA que controlase que cada parte del proyecto se realice con la calidad adecuada. Si lo piensas bien, en la mayor parte de las ocasiones esto recae en el jefe de proyecto o, incluso, en los propios consultores. Mantener documentada la toma de análisis (actas de reunión, etc), el diseño (documentos de diseño bien definidos), la implementación (plan de desarrollo, buenas prácticas, limpieza, encapsulamiento y reutilización de código) y la entrega (plan de pruebas, plan de cutover y plan de Go-Live). Pero si hubiese una figura velando porque esto se realice correctamente, estaría todo más ordenado. La parte del QC y UAT suele ser más común verlo de una forma u otra.
Por último un chiste sobre el tema que me ha parecido muy gracioso.
En la entrada «SAP CDS Core Data Services – ¿Qué son las CDS?» adelantamos que la herramienta ADT (ABAP Development Tools) es imprescindible para el uso de CDSs, pero ahí nos quedamos, ahora toca explicar qué es el ADT y cómo podemos empezar a usarlo. Pero, por supuesto, su uso no es únicamente para poder gestionar las CDSs Tiene muchos más usos. Vamos por partes.
¿Qué es SAP ADT?
ADT (ABAP Development Tools) es un conjunto de herramientas integradas en el entorno Eclipse por medio de un Plugin que permite a los desarrolladores trabajar de manera más moderna y eficiente en proyectos ABAP. A diferencia del tradicional SAP GUI, ADT proporciona una interfaz más intuitiva, con funcionalidades avanzadas que facilitan la escritura, depuración y gestión del código.
Características Principales de SAP ADT
SAP ADT trae consigo una serie de funcionalidades que optimizan el proceso de desarrollo, algunas de las cuales no estaban disponibles en SAP GUI.3.1.
Editor de Código Mejorado
El editor de código de SAP ADT ofrece una experiencia de edición mucho más rica en comparación con SAP GUI. Soporta características como:
Autocompletado: Facilita la escritura de código al sugerir funciones, variables y estructuras.
Resaltado de Sintaxis: Mejora la legibilidad del código con resaltado de diferentes componentes de ABAP.
Navegación Rápida: Permite saltar rápidamente entre funciones, clases y definiciones.
Herramientas de Refactorización
La capacidad de refactorizar código es esencial para mantener un código limpio y eficiente. Refactorizar es el proceso de mejorar la estructura interna del código de un programa sin alterar su comportamiento externo. SAP ADT permite:
Renombrado de Elementos: Cambiar el nombre de variables, clases y métodos sin romper referencias.
Extracción de Métodos: Facilita la reestructuración del código extrayendo segmentos en nuevos métodos.
Depuración Avanzada
La herramienta de depuración en SAP ADT es más intuitiva y poderosa que la disponible en SAP GUI. Ofrece:
Puntos de Ruptura Condicionales: Permiten detener la ejecución bajo condiciones específicas.
Visualización de Variables en Tiempo Real: Posibilita monitorear y modificar valores durante la ejecución.
Beneficios de Utilizar SAP ADT
Bueno, lo primero que habría que destacar es que es el camino claro que indica SAP de cara al desarrollo de S/4 HANA y de ciertas tecnologías en particular (CDS, RAP, ABAP Test Cockpit (ATC), etc.). Por lo tanto, un desarrollador debería estar atento al camino que toma su herramienta de trabajo y adaptarse al cambio, no vaya a ser que la carretera termine en una calle sin salida.
Pero, además de esto, que parece obvio, pero muchos no lo asimilan, ofrece mejoras en:
Usabilidad: SAP ADT ofrece una interfaz gráfica más moderna e intuitiva en comparación con SAP GUI. La integración con Eclipse proporciona una experiencia de usuario más fluida, con herramientas de navegación, autocompletado, y personalización del entorno de desarrollo.
Productividad en el desarrollo: Ofrece características avanzadas como la refactorización de código, depuración en tiempo real, y soporte para pruebas automatizadas con ABAP Test Cockpit (ATC). Estas herramientas permiten a los desarrolladores completar tareas más rápidamente y con menos errores, facilitando un desarrollo ágil y eficaz.
Gestión de versiones: ADT facilita la integración con sistemas de control de versiones como Git, permitiendo a los desarrolladores gestionar el código fuente de manera efectiva. Con esta integración, es posible realizar commits, merges y revertir cambios directamente desde el entorno de Eclipse, lo que asegura un control completo sobre el historial de cambios y facilita la colaboración en proyectos con múltiples desarrolladores.
Debugging: Ofrece características como puntos de ruptura condicionales, monitoreo en tiempo real de variables, y la posibilidad de modificar el flujo de ejecución mientras se depura.
Compatibilidad con todo el ecosistema S/4 HANA haciéndolo esencial para los desarrolladores que migran o desarrollan en este entorno.
Instalación y Configuración de SAP ADT
Para comenzar a usar SAP ADT, es necesario instalar Eclipse y luego agregar el plugin de ABAP Development Tools. Vamos a verlo paso a paso pero todos ellos están explicados en el siguiente enlace:
Hay que descargar la versión de Eclipse desde la web «Eclipse download page» tal y como comenta el tutorials del SAP Developer Center
SAP ADT Plugin
Una vez tengamos descargado y funcionando el Eclipse hay que instalar el Plugin de ADT en Eclipse. Se puede instalar directamente desde Eclipse utilizando el gestor de plugins con la URL https://tools.hana.ondemand.com/latest. Una vez más, lo mejor es seguir los pasos del tutorial del SAP Developer Center.
Configurar la conexión al sistema SAP
Una vez instalado el Plugin ADT en Eclipse tenemos que conectarnos al sistema. SAP. Para ello abrimos la perspectiva de ABAP en Eclipse.
Y se nos abrirá la visión de SAP ADT en Eclipse
Fijate bien en la barra de botones a ver si te suena alguno
A continuación tenemos que añadir la conexión al sistema que queramos pulsando Create an ABAP project. Esto abrirá una ventana con los sistemas que tengamos configurado en el SAP Logon para poder conectarnos.
Yo tengo algún que otro sistema configurado
En conclusión
Al principio se te puede hacer difícil salir de la comodidad de tu SAP GUI, y no es que el framework de trabajo Eclipse me encante, pero es el camino y, posteriormente, te va a dar más de lo que te quita, porque vas a estar al día de todas las tecnologías SAP.
Yo también he sido reacio al cambio, sobre todo porque no lo necesitaba y el SAP GUI me permitía navegar por los mares técnicos de SAP. Pero es como nadar con un solo brazo, puedes nadar, pero irás más lento y cuando te persiga un tiburón no podrás ir deprisa y te comerá el tiburón.
Con la evolución constante de SAP hacia S/4HANA y la adopción de tecnologías emergentes como CDS y RAP, ADT se posiciona como una herramienta imprescindible para cualquier desarrollador que quiera estar a la vanguardia. Luego no digáis que no lo sabíais.
En este artículo hemos sentado las bases de qué es el ADT, sus beneficios y usos y cómo se instala y se configura inicialmente. En posteriores artículos intentaré hacer ejemplos de uso, y cosas más concretas como son:
Manejo básico en nuestro día a día como hacemos en SAP GUI
Vamos a hablar del pasado-presente-futuro del acceso a los datos de la base de datos de los sistemas SAP. ¿Por qué digo pasado-presente-futuro?
Pasado: Porque es algo que salió sobre 2012 (12 años hace) dentro de la solución de acceso a datos de HANA. En ese momento, claro, habría entre 0 y 1 implantación de SAP HANA en España, pero el dato está ahí.
Presente: Porque ahora mismo ya lo estamos usando. Aunque no lo sepas, el estándar ya usa CDS para muchos de los procesos estándar y las búsquedas de la herramienta.
Futuro: Porque para mucha gente esto es nuevo (que no lo es) y siguen tirando sus Selects a base de datos. SAP ha trazado un camino claro hacia el futuro con CDS, destacando su importancia en la optimización del acceso a datos en un entorno de crecimiento exponencial de los mismos. Además CDS no solo facilita este acceso, sino que también se integra de manera efectiva con otras tecnologías emergentes, como RAP, para ofrecer soluciones de desarrollo modernas y escalables.
Esto está muy bien, pero no sabemos qué es los CDS Core Data Services. Vamos a verlo.
CDS en tus manos
¿Qué son las CDS Core Data Services?
SAP CDS es un paradigma de programación para la plataforma SAP ABAP introducido inicialmente en SAP NetWeaver 7.4 SP05 y SAP HANA SPS6. Su enfoque principal es optimizar las operaciones de bases de datos, permitiendo a los desarrolladores crear modelos de datos eficientes y robustos que se integran perfectamente con SAP HANA y otras plataformas SAP.
Voy a traducirlo.
CDS permite a los desarrolladores crear modelos de datos abstractos que luego se traducen en consultas SQL optimizadas para ejecutarse en SAP HANA. Esta abstracción es crucial para realizar operaciones complejas de bases de datos de manera más eficiente y coherente. Por ejemplo, en lugar de escribir consultas SQL complejas y propensas a errores, los desarrolladores pueden definir vistas CDS que encapsulan la lógica y el comportamiento de los datos, lo que facilita el mantenimiento y la evolución del sistema.
¿Lo hemos entendido?
Lo intento explicar mejor.
Básicamente, una CDS te permite crear una «vista» o «representación» de los datos que necesitas extraer de la base de datos, pero con muchas ventajas adicionales.
En términos simples, una CDS es como un «filtro inteligente» que se coloca entre la base de datos y la aplicación. Este filtro te permite seleccionar y organizar los datos de la manera exacta que necesitas, sin tener que escribir consultas SQL complejas cada vez. Además, este filtro puede incluir reglas de negocio, lógica adicional, y definiciones de seguridad, todo integrado en una única definición. Todo esto se ejecuta en la capa In-Memory de SAP HANA, dejando que sea SAP HANA quien gestione ciertos aspectos de rendimiento y dependencias entre datos.
Pero entonces ¿Qué diferencia hay entre una vista de la SE11 y una CDS?
Pues mucha, muchísima. Y a varios niveles.
Optimización y funcionalidad
Las CDS están diseñadas específicamente para aprovechar al máximo SAP HANA, lo que les permite ejecutar consultas de manera más eficiente y rápida, gracias a la capacidad de procesamiento en memoria de HANA. En contraste, las vistas de la SE11, aunque funcionan en HANA, no están tan optimizadas para esta base de datos, lo que puede hacerlas menos eficientes en términos de rendimiento.
Capacidad funcional
Las CDS ofrecen un conjunto de herramientas mucho más amplio y avanzado. Por ejemplo, permiten incluir lógica de negocio, realizar cálculos complejos, aplicar anotaciones para definir comportamientos específicos, y gestionar uniones de datos de forma más sofisticada. Además, las CDS son altamente flexibles y modulares, lo que facilita su mantenimiento y actualización en comparación con las vistas de la SE11, que tienden a ser más rígidas y difíciles de modificar cuando cambian los requisitos.
Integración con tecnologías modernas
Las CDS están claramente diseñadas para el futuro. Se integran perfectamente con SAP Fiori y RAP, permitiendo la exposición de datos a través de servicios OData, algo crucial para el desarrollo de aplicaciones modernas y basadas en servicios. Por otro lado, las vistas SE11, aunque útiles, no están tan bien adaptadas para estos escenarios de aplicación moderna, lo que puede limitar su uso en proyectos que requieren conectividad y exposición de datos a través de servicios web.
Seguridad
Las CDS incorporan controles de acceso y autorizaciones directamente en la definición de la vista, lo que permite un control más detallado y seguro sobre quién puede acceder o modificar los datos. Las vistas de SE11, por su parte, dependen más de configuraciones externas para la seguridad, lo que las hace menos integradas en este aspecto.
Componentes Principales de CDS
SAP CDS se basa en tres componentes clave que permiten a los desarrolladores crear modelos de datos optimizados:
Vistas CDS: Las vistas CDS son la base de SAP CDS. Permiten definir estructuras de datos y consultas que se ejecutan directamente en la base de datos, actuando como una capa de abstracción sobre las tablas subyacentes. Estas vistas facilitan el acceso y la manipulación de los datos, optimizando las consultas SQL y mejorando el rendimiento general.
Anotaciones: Las anotaciones en CDS permiten enriquecer los modelos de datos con metadatos que definen características importantes como la seguridad, las relaciones entre entidades, y el comportamiento de los datos. Esto ayuda a crear modelos de datos que no solo son eficientes, sino también seguros y coherentes con la lógica de negocio.
Funciones de CDS: Las funciones de CDS son operaciones predefinidas que pueden aplicarse directamente sobre los datos en la capa de la base de datos, mejorando la eficiencia al realizar cálculos complejos o transformaciones de datos. Son parecidas a las funciones que podemos usar en SQL (SUM, MAX, MIN, etc.) pero más potentes porque se aplican directamente en las definiciones de las vistas CDS, lo que permite que la lógica de negocio se implemente y se ejecute en la base de datos, mejorando la eficiencia y reduciendo la necesidad de procesar los datos en la capa de aplicación.
La Herramienta Necesaria: ADT (ABAP Development Tools)
Para gestionar y desarrollar con CDS, es esencial utilizar ABAP Development Tools (ADT) en el entorno de desarrollo Eclipse. ADT proporciona un conjunto de herramientas específicas para trabajar con CDS, que incluyen un editor avanzado de código, herramientas de depuración, y funciones para la gestión y visualización de las vistas CDS.
Sobre ADT tengo previsto hacer un artículo explicando más pormenorizadamente sus capacidades, como instalarlo y su uso. No vanos a detenernos en ello ahora.
Beneficios de Usar SAP CDS
Más o menos los hemos ido viendo durante el artículo, pero lo podemos resumir en lo siguiente:
Rendimiento Mejorado: CDS maximiza el uso de SAP HANA, reduciendo la latencia y mejorando significativamente el rendimiento de las consultas. Es la forma nativa de explotar el potencial del procesamiento en Memoria de HANA.
Integración Nativa: CDS está profundamente integrado en el ecosistema SAP, lo que facilita la creación de aplicaciones que pueden interactuar con diferentes módulos de SAP, garantizando una interoperabilidad fluida. Siendo la base de tecnologías como RAP (RESTful ABAP Programming) o OData V4.
Facilidad de Mantenimiento: Dado que las vistas CDS son declarativas el mantenimiento y las actualizaciones de las aplicaciones son más simples y menos propensas a errores. La lógica de negocio queda claramente definida y separada de la lógica de presentación, mejorando la mantenibilidad del código. De todo esto y de como usarlo hablaremos en otro artículo concreto.
En conclusión
Sirva este artículo como introducción a SAP CDS si es que alguien no lo conocía ya. Quiero hacer una serie sobre como usar CDSs y ejemplos más palpables de las ventajas que ofrece.
En otros lenguajes de programación que no están tan ligados al núcleo de un aplicativo empresarial, es común y casi obligatorio ver el uso de control de versiones y repositorios como GitHub, GitLab, etc. para gestionar y colaborar en el desarrollo del código. Sin embargo, en el caso de ABAP, un lenguaje que está profundamente arraigado dentro del framework SAP Netweaver, que tiene su propio repositorio y gestor de versiones, la adopción de herramientas modernas como Git para ABAP ha sido más lenta.
Es aquí donde abapGit entra en escena, proporcionando una solución clave para los desarrolladores ABAP que quieren aprovechar las ventajas del control de versiones distribuido. Pero antes de nada, veamos el escenario habitual en otros lenguajes y en entorno de desarrollo conjunto distribuido. Lo primero que tenemos que saber es qué es eso de Git.
¿Qué es Git?
Git es un sistema de control de versiones distribuido diseñado para rastrear los cambios en archivos de código fuente y facilitar la colaboración entre múltiples desarrolladores en un proyecto. Fue creado por Linus Torvalds en 2005, inicialmente para el desarrollo del Kernel de Linux. Es utilizado principalmente en el desarrollo de software, pero también puede aplicarse a otros tipos de proyectos donde se necesita llevar un control detallado de cambios en archivos.
Características Claves de Git
Las características que hacen de Git una tecnología tan potente son:
Control de versiones distribuido: A diferencia de los sistemas centralizados de control de versiones, en Git cada desarrollador tiene una copia completa del historial del proyecto en su máquina local, lo que permite trabajar de manera independiente y sin conexión.
Snapshots: En lugar de registrar diferencias entre versiones de los archivos, Git toma «instantáneas» del estado de los archivos en cada commit. Si no hay cambios en un archivo, Git solo referencia la versión anterior.
Integración y colaboración: Git facilita la integración continua y la colaboración mediante ramas (branches), que permiten que varios desarrolladores trabajen en diferentes características de un proyecto sin interferir con el trabajo de otros. Posteriormente, las ramas pueden fusionarse (merge) de manera segura.
Rendimiento eficiente: Dado que Git opera de manera distribuida y guarda versiones localmente, la mayoría de las operaciones (como commits, comparaciones y creación de ramas) son extremadamente rápidas, ya que no dependen de un servidor remoto.
Compatibilidad con plataformas como GitHub: Git es la tecnología subyacente que soporta plataformas populares como GitHub, GitLab, Bitbucket, las cuales añaden características adicionales como la gestión de proyectos, seguimiento de errores y funciones de revisión de código.
Beneficios de usar Git
Seré breve, os podéis imaginar los beneficios, viendo las características clave.
Seguridad: El historial de cambios en Git está protegido contra alteraciones accidentales o malintencionadas.
Flexibilidad: Git es útil para proyectos de cualquier tamaño y es compatible con numerosos flujos de trabajo.
Desarrollo paralelo: Facilita el trabajo simultáneo de varios desarrolladores en diferentes partes de un proyecto, permitiendo integraciones y fusiones de código (Merge) sin perder la coherencia del proyecto.
Ya sabemos lo que es Git y sus características, pero nos falta saber que es eso de Github o GitLab.
¿Qué es GitHub?
GitHub es una plataforma de desarrollo colaborativo que permite a los programadores y equipos gestionar proyectos de software utilizando el sistema de control de versiones Git. GitHub proporciona un entorno basado en la web donde los desarrolladores pueden alojar y compartir sus proyectos de código, colaborar en equipo, y realizar un seguimiento de los cambios mediante el uso de repositorios.
No vamos a profundizar más en GitHub, puesto que esta basado en Git (ya lo hemos explicado) aportando una capa por encima con más funcionalidades de gestión de Proyectos.
Vamos ahora, una vez sabemos lo que es Git y lo que es GitHub (o similares), vamos a ver qué es abapGit.
¿Qué es abapGit?
Como podemos ver en la Help de SAP:
abapGit es un cliente Git desarrollado por código abierto para que el servidor ABAP importe y exporte objetos ABAP entre sistemas ABAP.
Con abapGit, puede exportar sus objetos ABAP de cualquier sistema a otro, normalmente de local a en la nube o de un sistema en la nube a otro.
Pero en SAP BTP es un framework donde desplegar aplicaciones de muchos tipos ya sea SAP Build Apps, Fiori, CPI, Python, Go, Ruby, etc. Digamos que en el framework de trabajo de SAP BTP usar una solución Git es practicamente obligatorio.
Pero nosotros vamos a algo más mundano, queremos integrar la tecnología Git dentro de nuestros proyectos ABAP de toda la vida, con su SE80, SE38, sus paquetes de desarrollo, etc.
Por lo tanto, podemos decir que abapGit es un cliente de Git específico para ABAP, que permite a los desarrolladores trabajar con un control de versiones distribuido externo dentro del entorno SAP. Desarrollado como un proyecto de código abierto por la comunidad, abapGit permite exportar e importar objetos ABAP a repositorios externos como GitHub, GitLab o Bitbucket, lo que hace posible integrar flujos de trabajo modernos en sistemas SAP.
¿Qué puedo hacer con abapGit?
Pues SAP tiene varios tutoriales que nos pueden ayudar con esto:
Podemos ampliar esas dos tareas que propone el Learning de SAP por la siguiente lista:
Versionado del código ABAP: Permite realizar Commits del código ABAP en un repositorio Git (GitHub, GitLab, etc), creando un historial de cambios que facilita la colaboración entre múltiples desarrolladores.
Colaboración en equipo: Con la capacidad de clonar y fusionar repositorios, los equipos de desarrollo pueden trabajar en diferentes características del proyecto simultáneamente sin interferir entre sí, lo que mejora la productividad y reduce los errores.
Migración de código ABAP entre sistemas: abapGit facilita la migración de objetos ABAP de un sistema on-premise a la nube, o entre diferentes sistemas SAP. Esto es especialmente útil en proyectos de migración a SAP S/4HANA o SAP BTP. Esto es lo que comenta el enlace de SAP Learning que he puesto antes.
Integración con herramientas CI/CD: abapGit permite integrar proyectos ABAP en flujos de trabajo de integración y entrega continua (CI/CD), facilitando un enfoque ágil al desarrollo.
Exportación e importación de objetos: abapGit facilita la exportación de objetos ABAP, como clases, funciones, y programas, a repositorios Git. Desde allí, es posible importar estos objetos a otros sistemas SAP, lo que simplifica la colaboración entre diferentes entornos de desarrollo. Y esto es lo que comenta el otro enlace de SAP Learning que he puesto. Sobre este punto, quiero hacer una puntualización en el punto siguiente.
Importación de funcionalidad colaborativa: Existen proyectos de código abierto subidos a GitHub con funcionalidades concretas que están a nuestra disposición para importarlos en nuestro sistema SAP por medio de abapGit. Obviamente, con esto hay que tener cierto cuidado porque estamos importando código de otra persona. Tienen que ser fuentes contrastadas y validadas por la comunidad. Pero, para mi, es un aspecto fundamental ya que alimenta el conocimiento global y simplifica muchas tareas que alguien ya pensó e implementó. Ejemplos de esto pueden ser:
OpenAPI: El motivo de escribir esta entrada es básicamente poder explicar OpenAPI en SAP para nuestros servicios OData. Por lo tanto este punto lo explicaremos en la entrada correspondiente, cuando la publique actualizaré esta para poder el link.
ABAP2XLS: Proporciona un conjunto de opciones para el trabajo con excel desde ABAP, simplifica mucho el proceso de manejar Excel con muchas demos y muchas opciones.
¿Cómo instalar abapGit en mi sistema?
Pues es bastante sencillo, más que nada porque está perfectamente explicado en varios sitios. Por ejemplo:
Standalone version: Se trata de un report que sirve para realizar la conexión de Importación (que puede ser desde un repositorio tipo GitHub) y Exportación a local.
Developer version: Es la versión que te permite trabajar con tus proyectos ABAP en un repositorio Git con toda la funcionalidad. Importar, Exportar, trabajar colaborativamente, etc. Para esta versión tienes que instalar primero la versión Standalone para descargarte el proyecto abapGit tal y como comenta el tutorial. Ten en cuenta que quizás tengas que instalar el certificado de GitHub en el sistema para poder establecer la conexión con GitHub, viene bien explicado en SSL Setup. También se puede instalar de forma offline descargándote el proyecto en Zip y subiéndolo al report de Standalone.
Y es que Git no solo vale para la gestión de cambios y trabajo concurrente, como hemos visto aporta la funcionalidad de Integración con herramientas CI/CD, esto ¿Qué es?.
Integración Continua (CI)
La Integración Continua es una práctica en la que los desarrolladores integran su código en un repositorio compartido, como puede ser GitHub, varias veces al día. Cada vez que se hace una integración, se ejecuta una serie de pruebas automáticas para asegurarse de que el nuevo código no introduzca errores ni rompa las funcionalidades existentes. El objetivo es detectar y corregir problemas lo más rápido posible.
Entrega Continua (CD)
Ojo cuidado con esto. en la Entrega Continua, una vez que el código pasa las pruebas automáticas y es integrado, se prepara automáticamente para su despliegue en el entorno de producción.
Obviamente, en estas prácticas se puede llegar a la profundidad que se requiera, no es todo o nada. Hay mucho más que aprender de CI/CD pero yo no soy el más indicado para explicar más allá de la teoría. Para mi, viniendo del mundo SAP, con su cola de transportes, su paso a producción bajo ticket de Remedy o Service Now, y sus UATs, me parece complicado y peligroso. No obstante SAP ya está en ello, podemos ver la charla de SAP Teched 2020 «DevOps for ABAP? Try the Git-Enabled Change and Transport System | SAP TechEd in 2020«
Madre mía!
Podéis verlo en este video.
En Conclusión
El objetivo de esta entrada es servir de base a otras entradas en las que hago uso de ABAPGit para importar proyectos ABAP en el sistema. Es muy útil, ya no solo para tener un repositorio de tus desarrollo, si no también para utilizar proyectos ABAP de la comunidad que aporten valor inmediato a tu proyecto.
Llevo desde los 18 años programando, y empecé por curiosidad y en casa. Es algo que se me da bien, me gusta y me genera satisfacción «crear» algo donde no lo había. Mi perfil profesional actual es bastante amplio, pero nunca quiero dejar ese aspecto de mi día día. Es algo que me llena, que me alegra…. hasta que veo algunas masacres de código que hay por el mundo, que me entran ganas de matar.
if dino_aux2-tipo = ‘velociraptor’ and dino_aux2-enfadado = ‘true’ or dino_tocho = ‘suelto’. Write:/ ‘Me voy’. endif. Viendo tu código te tenían que haber despedido hace tiempo, pero no habría película
Hoy voy a hablar de la calidad del código, no solo en su efectividad, también en su eficiencia, su facilidad de lectura y mantenimiento. A muchos les parecerá una tontería, algo sin importancia, pero un buen código simplifica mucho el mantenimiento, la reutilización, la lectura y documentación.
CleanABAP
Existe un proyecto en GitHub llamado Clean ABAP donde la comunidad de desarrolladores ABAP han sacado una guía de estilo de desarrollo ABAP con las mejores prácticas. Además está en varios idiomas, incluido el Español lo puedes ver aquí.
Y claro, yo iba a escribir mi libro de buenas prácticas desde mi punto de vista. Cosa que he hecho en algún proyecto al ver los desastres que la gente generaba en el sistema. Pero, al ver que ya había un consenso entre desarrolladores ABAP, y que no estaba solo en esto, pues mejor. Lo que voy a hacer es extraer de la guía de estilo CleanABAP aquellas recomendaciones que vea más necesarias. En la guía de estilo (lectura recomendadísima), se dividen las recomendaciones por áreas, vamos a respetarlas por si quieres ir a ver la fuente.
NOTA: Si estás viendo esto desde un móvil o tablet mejor en horizontal, las líneas de código se te van a cortar y hay cosas que no entenderás. No obstante, es preferible que lo leas desde el PC.
Formato
Optimiza para lectura, no para escritura
Siempre escribe pensando en la legibilidad del código, no en lo rápido que puedas escribirlo.
Bueno, yo con esta ya si que me corto las venas. Es un &#+%€ botón, pulsar un botón y te hace gran parte del trabajo.
Usa el Pretty Printer.
Usa el Pretty Printer
En serio. Usa el Pretty Printer.
Usa la configuración de Pretty Printer de tu equipo
Enlazado con lo anterior, tampoco estamos hablando de ingeniería. Es configurar tu Pretty Printer para que actúe de la forma que se consensue en tu equipo de trabajo. Yo, personalmente me gusta así:
Y esto es por lo siguiente:
Sangrar: Obvio, que el texto tenga sus correspondientes sangrías que te indiquen el nivel en el que estás es fundamental.
Conversión mayúsc./minúsc.: A mi me parece muy interesante que las palabras clave sean mayúsculas para ver claramente la acción que se está realizando e identificar las sentencias ABAP de variables, parámetros y literales.
" Ejemplo sin palabras clave mayúsculas select partner into lv_partner from but000 where bu_group = lv_clientes and xdele = abap_false and type = 1.
" Ejemplo con palabras clave mayúsculas SELECT partner INTO lv_partner FROM but000 WHERE bu_group = lv_clientes AND xdele = abap_false AND type = 1.
Por favor, usa el Pretty Printer.
No más de una sentencia por línea de código
Cada línea de código debe contener solo una sentencia, evitando mezclar varias operaciones en una sola línea.
Para mi esto es especial para los IFs con múltiples condiciones. Todo de seguido no se ve claramente.
" Ejemplo Incorrecto IF lv_total > 100 And lv_is_customer = 'X' AND lv_country = 'ES'. lv_discount = lv_total * 0.1. ELSE. lv_discount = 0. ENDIF.
" Ejemplo Correcto IF lv_total > 100 AND lv_is_customer = 'X' AND lv_country = 'ES'. lv_discount = lv_total * 0.1. ELSE. lv_discount = 0. ENDIF.
Aquí la posición de los AND y OR ya es manía personal, hay quien los pone al principio, a mi me gusta ponerlo al final y alinear las variables, los operadores y los AND/OR.
Mantén una longitud de línea razonable
Si la línea de código es demasiado larga, divídela en varias líneas para que sea más fácil de leer y seguir.
" Ejemplo Incorrecto SELECT carrid connid fldate FROM sflight INTO TABLE lt_sflight WHERE carrid = 'LH' AND connid = '0400' AND fldate = '20231010'.
" Ejemplo Correcto SELECT carrid connid fldate INTO TABLE lt_sflight FROM sflight WHERE carrid = 'LH' AND connid = '0400' AND fldate = '20231010'.
Vamos, no hay color. Mi manía personal es ponerlo en ese orden (SELECT, INTO, FROM, WHERE), y alineando desde el INTO. Además con las sentencias ABAP alineadas el código tiene más aire y se lee mejor. Se identifica claramente qué se selecciona, a donde se guarda, de qué tablas y con qué condiciones.
Usa una línea en blanco para separar cosas, pero no más
Utiliza una línea en blanco para separar lógicamente secciones del código, como declaraciones de variables y bloques de código, pero evita poner líneas en blanco innecesarias.
Los bloques de sentencias han de estar separados para su entendimiento. Todo junto no se lee bien.
" Ejemplo Incorrecto DATA: ls_order TYPE zorder, lv_total TYPE p DECIMALS 2, lv_discount TYPE p DECIMALS 2. ls_order-order_id = 'ORD001'. ls_order-customer_id = 'CUST001'. ls_order-status = 'OPEN'. lv_total = 500. lv_discount = lv_total * 0.1. ls_order-total_amount = lv_total. ls_order-discount_amount = lv_discount. INSERT zorder FROM ls_order.
" Ejemplo Correcto DATA: ls_order TYPE zorder, lv_total TYPE p DECIMALS 2, lv_discount TYPE p DECIMALS 2.
Alinea asignaciones al mismo objeto, pero no a objetos diferentes
Cuando asignas valores a varios atributos de un mismo objeto, puedes alinearlos para mejorar la legibilidad, pero evita alinear asignaciones entre diferentes objetos.
" Cómo lo hago yo lo_instance->set_data( EXPORTING iv_name = lv_name iv_age = lv_age iv_address = lv_address iv_order_id = lv_order_id ).
Fíjate en el alineamiento de los =, hace que sepas claramente identificar parámetros de variables. Esto también lo suelo hacer los IFs con los comparadores, pero eso ya es manía personal.
" Ejemplo Incorrecto IF lv_status EQ 'A' AND lv_subtype NE 'X' AND lv_amount GT 100. lv_result = 'Valid'. ELSE. lv_result = 'Invalid'. ENDIF.
" Cómo lo hago yo IF lv_status EQ 'A' AND lv_subtype NE 'X' AND lv_amount GT 100. lv_result = 'Valid'. ELSE. lv_result = 'Invalid'. ENDIF.
Nomenclatura
Usa nombres descriptivos
Los nombres de variables, clases y métodos deben ser lo suficientemente claros para que cualquier desarrollador entienda su propósito sin necesidad de contexto adicional. Por ejemplo
" Declaraciones no descriptivas DATA: lv_amt TYPE i, lt_cust TYPE TABLE OF but000, lt_items_aux TYPE TABLE OF crmd_orderadm_i.
" Declaraciones con nombres descriptivos DATA: lv_total_amount TYPE i, lt_customers TYPE TABLE OF but000, lt_items_completed TYPE TABLE OF items.
No cuesta nada y se lee todo mejor, eso sí, se consecuente con usar cada uno para lo que es, no vayas a meter en lt_items_completed cualquier tipo de posiciones de pedido porque te venga bien.
Usa sustantivos para las clases y verbos para los métodos
Las Clases deberían representar conceptos o entidades y, por lo tanto, se nombran como sustantivos.
" Ejemplos order_calculator order_utils
Los Métodos representan acciones o comportamientos, por lo que deben nombrarse con verbos.
Para mejorar la legibilidad en ABAP, se prefiere el uso de snake_case en lugar de camelCase o PascalCase en variables y métodos. El uso de snake_case es una convención ampliamente utilizada en el código ABAP debido a su compatibilidad con otras herramientas del ecosistema SAP y porque ayuda a mejorar la claridad del código, haciéndolo más legible y fácil de seguir para los desarrolladores.
" Ejemplos Incorrectos DATA: TotalAmountDue type p decimals 2. DATA: itemstoadd type table of items.
" Ejemplos Correctos DATA: lv_total_amount_due TYPE p DECIMALS 2, lt_items_to_add TYPE TABLE OF items.
Constantes
Usa constantes en lugar de números mágicos
Evita usar números sin contexto directamente en el código. En su lugar, define constantes para mejorar la legibilidad.
" Ejemplo Incorrecto IF lv_value > 42.
" Ejemplo Correcto IF lv_value > gc_max_allowed.
Sabemos que el 42 es «El sentido de la vida, el universo y todo lo demás» pero a lo mejor en tu proceso no es el sentido de ese número. Usa constantes, puedes declararlas en un INCLUDE TOP o bien en una clase estática que aglutine varias constantes.
Prefiere clases de enumeración a interfaces de constantes
Esto lo he añadido por el punto anterior. Lo que yo suelo hacer es crear una serie de clases UTIL con métodos estáticos, con un sentido funcional cada una, y sus constantes correspondientes. Voy a poner un ejemplo:
CLASS zcl_crm_ofertas_util DEFINITION. PUBLIC SECTION.
" Constantes para los estados de la oferta CONSTANTS: c_estado_abierto TYPE char10 VALUE 'E0001', c_estado_cerrado TYPE char10 VALUE 'E0002'.
" Métodos estáticos CLASS-METHODS: get_datos_oferta IMPORTING iv_oferta_id TYPE char10 RETURNING VALUE(rt_oferta_datos) TYPE TABLE OF zcrm_oferta.
CLASS-METHODS: get_interlocutores IMPORTING iv_oferta_id TYPE char10 RETURNING VALUE(rt_interlocutores) TYPE ztt_interlocutores. ENDCLASS.
Y las constantes c_estado_abierto y c_estado_cerrado podemos usarlo en cualquier código para comprobar si un pedido tiene ese estado.
IF lv_estado_pedido EQ zcl_order_util=>c_estado_abierto. " Hacer cosas ENDIF.
Variables
Prefiere declaraciones in-line que al inicio
Este apartado no estoy al 100% de acuerdo, porque soy de vieja escuela, antes de que las declaraciones In-line estuviesen disponibles y suelo hacer bastantes declaraciones al inicio. No obstante, creo que tiene bastante razón.
" Ejemplo Incorrecto METHOD calculate_discount. DATA: lv_discount TYPE p DECIMALS 2, lv_total_amount TYPE p DECIMALS 2, lt_clientes TYPE TABLE OF but000.
SELECT * INTO TABLE @DATA(lt_clientes) FROM but000 WHERE bu_group EQ zcl_bp_util=>c_agrupación_cliente. ENDMETHOD.
Lo importante es conocer las declaraciones In-line que son muy útiles y aportan claridad y limpieza al código.
No encadenes declaraciones
Cada declaración debe ocupar una línea por sí misma. Esto facilita el seguimiento de las variables.
" Ejemplo Incorrecto DATA: lv_value TYPE i, lv_discount TYPE p, lv_total TYPE p.
" Ejemplo Correcto DATA: lv_value TYPE i, lv_discount TYPE p, lv_total TYPE p.
A lo que yo añado lo siguiente
Usa «DATA:» y evita usar múltiples DATA
Entras en un código y te encuentras con esto
DATA lv_es_cliente TYPE bu_partner. DATA lt_pedidos_abiertos TYPE TABLE OF zpedidos. DATA ls_pedidos_abiertos TYPE zpedidos. DATA lv_fecha_creacion TYPE datum. DATA lv_sociedad TYPE werks. DATA lt_pedidos_cerrados TYPE zpedidos.
Pero ¿Para qué ponemos tantos DATA. Si ponemos solo un DATA: el Pretty Printer se va a encargar de darle mucho aire y alinear los TYPE.
DATA: lv_es_cliente TYPE bu_partner. lt_pedidos_abiertos TYPE TABLE OF zpedidos. ls_pedidos_abiertos TYPE zpedidos. lv_fecha_creacion TYPE datum. lv_sociedad TYPE werks. lt_pedidos_cerrados TYPE zpedidos.
Vamos. no hay color, y eso que he puesto un ejemplo con seis líneas, he llegado a ver decenas de DATA juntos. Ya sabes, usa el Pretty Printer.
Tablas
Prefiere INSERT INTO TABLE a APPEND TO
Usar INSERT INTO TABLE es más versátil y claro para la inserción de datos en tablas internas. Además el uso del APPEND da errores en las tablas de tipo SORTED y en INSERT INTO TABLE lo gestiona bien.
" Ejemplo Incorrecto APPEND ls_cliente TO lt_clientes.
" Ejemplo Correcto INSERT ls_cliente INTO TABLE lt_clientes.
Ocupa lo mismo y no da problemas.
Prefiere LINE_EXISTS a READ TABLE o LOOP AT
En lugar de leer tablas para verificar si una línea existe, usa la función LINE_EXISTS, que es más clara y eficiente. Esto no lo suelo usar mucho, porque soy vieja escuela, pero me parece muy interesante.
" Ejemplo Incorrecto READ TABLE lt_table WITH KEY id = lv_id TRANSPORTING NO FIELDS. IF sy-subrc = 0. WRITE: 'La línea existe'. ELSE. WRITE: 'La línea no existe'. ENDIF.
" Ejemplo Correcto IF line_exists( lt_table[ id = lv_id ] ). WRITE: 'La línea existe'. ELSE. WRITE: 'La línea no existe'. ENDIF.
Strings
Usa | para construir textos
En ABAP, puedes usar | para concatenar y construir cadenas de forma más limpia que con las antiguas funciones CONCATENATE.
" Ejemplo menos eficiente CONCATENATE lv_name lv_surname INTO lv_fullname.
Este es uno de los principios básicos de CleanABAP. Es mejor hacer un método que haga una cosa cada vez para que el código se pueda leer de forma sencilla y coherente. Para que el método haga una cosa nos tenemos que asegurar que:
Tiene pocos parámetros: Un método que hace una sola cosa debería tener pocos parámetros de entrada. Tener muchos parámetros indica que el método podría estar haciendo más de una tarea
No tiene parámetros booleanos de entrada: Los parámetros booleanos en un método pueden ser una señal de que el método realiza dos cosas: una cuando el valor es verdadero y otra cuando es falso.
Tiene exactamente un parámetro de salida: Un método que hace una sola cosa debería tener solo un resultado. Si devuelve más de un valor, probablemente esté realizando múltiples tareas
Es corto: Un método debe ser corto y directo. Si un método es demasiado largo, es una señal de que está realizando múltiples tareas.
Desciende un nivel de abstracción: Un buen método debe enfocarse en un solo nivel de abstracción. No debe mezclar operaciones de bajo nivel (como acceso a base de datos) con operaciones de alto nivel (como lógica de negocio)
Lanza un solo tipo de excepción: Si un método lanza múltiples tipos de excepciones, es probable que esté haciendo más de una cosa
No puedes extraer más métodos de él con un significado claro: Si no puedes dividir un método en varios métodos más pequeños que tengan un propósito claro y diferenciado, entonces probablemente el método está bien estructurado.
No puedes agrupar sus sentencias en secciones lógicas: Si las sentencias de un método se pueden agrupar en diferentes secciones, es probable que el método esté realizando múltiples tareas.
Mensajes
Haz que los mensajes sean fáciles de encontrar
Para hacer los mensajes fáciles de encontrar en una búsqueda desde la transacción SE91. Realmente yo usaba la sentencia incorrecta, pero la recomendación es no usar eso.
" Ejemplo Incorrecto IF 1 = 2. MESSAGE e001(ad). ENDIF.
" Ejemplo Correcto MESSAGE e001(ad) INTO DATA(message).
Comentarios
Exprésate en código, no en comentarios
El código bien escrito debe ser lo suficientemente claro para no requerir comentarios excesivos.
" Ejemplo Incorrecto " Calcula el total con el descuento lv_total = lv_total - lv_discount.
Usa nombres descriptivos en lugar de comentarios, ya que esto hace el código más autoexplicativo.
Los comentarios no son excusa para nombrar mal objetos
Los nombres de variables y objetos deben ser claros y descriptivos por sí mismos, sin depender de comentarios para su explicación.
" Ejemplo Incorrecto " Cantidad Total DATA: lv_tot_amnt TYPE i.
" Ejemplo Correcto DATA: lv_total_amount TYPE i.
El nombre de la variable debe ser suficientemente descriptivo para evitar depender de comentarios innecesarios.
Usa métodos en lugar de comentarios para segmentar tu código
Es más eficiente y claro usar métodos con nombres descriptivos para organizar las diferentes tareas dentro del código. Esto mejora la legibilidad y el mantenimiento del código, además de seguir el principio de hacer una sola cosa en cada método.
Los comentarios pueden volverse obsoletos o estar mal escritos, lo que puede generar confusión. Sin embargo, los métodos con nombres claros y bien definidos hacen que el propósito de cada sección sea evidente, eliminando la necesidad de comentarios explicativos.
" Ejemplo Incorrecto METHOD process_order. " Validación del cliente IF lv_customer_id IS INITIAL. RETURN. ENDIF.
" Calcular el total lv_total = calculate_total( lt_items ).
" Aplicar el descuento IF lv_discount > 0. lv_total = lv_total - lv_discount. ENDIF.
" Guardar el pedido en la base de datos save_order( lv_order_id ). ENDMETHOD.
METHOD save_order. INSERT INTO zorders VALUES iv_order_id. ENDMETHOD.
El diseño va en los documentos de diseño, no en el código
Evita incluir detalles de diseño en el código, ya que esto pertenece a la documentación externa. El diseño debe documentarse fuera del código para evitar que el código se vuelva innecesariamente complicado de leer.
" Ejemplo Incorrecto " Este método sirve para crear pedidos de venta con los datos de " entrada de cliente, datos organizativos, productos y precios. " Los tipos de posición se calcularán en base al tipo de cliente y el " tipo de pedido que se quiere crear. " Para eso se llamará a la tabla ZTB_TIPO_POS y se recuperarán los " tipos de posición. " El estado del pedido será siempre "Abierto" METHOD crear_pedido_ventas.
Nadie se lee esto, además puede quedar fácilmente obsoleto al cambiar el contenido del método. Si el código se entiende, no hace falta hacer explicaciones de más.
Usa » para comentar, no *
Es preferible usar » para líneas de comentario porque se identan automáticamente al nivel donde aplican al usar Pretty Printer.
" Ejemplo Incorrecto CASE lv_estado. WHEN c_abierto. * Comentario en abierto
WHEN c_en_proceso. * Comentario en proceso
WHEN c_cerrado. * Comentario en cerrado
ENDCASE.
" Ejemplo Correcto CASE lv_estado. WHEN c_abierto. " Comentario en abierto
WHEN c_en_proceso. " Comentario en proceso
WHEN c_cerrado. " Comentario en cerrado
ENDCASE.
Borra el código en lugar de comentarlo
El código obsoleto debe ser eliminado en lugar de ser comentado para evitar confusión. Para algo está la gestión de versiones, el código que pasa por muchas manos y correcciones se vuelve imposible de leer.
No agregues prototipos ni comentarios de fin de métodos (INTERESANTE)
Los comentarios estándar de la firma de métodos o performs no aportan valor y generan ruido en el código. Estos comentarios pueden haber tenido sentido décadas atrás, cuando los entornos de desarrollo eran limitados, pero en los entornos modernos de ABAP (SE24, SE80, ABAP Development Tools en Eclipse), ya no son necesarios, porque la firma del método está fácilmente accesible con herramientas integradas.
" Ejemplo Incorrecto *&---------------------------------------------------------------------* *& Form CHECK_ORDER *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * -->P_LV_ABAP_BOOL text * -->P_LV_COUNTRY text * -->P_LV_CUSTOMER_ACTIVE text * -->P_LV_HAS_DISCOUNT text * <--P_LV_TOTAL text * <--P_LV_SPECIAL_CUSTOMER text *---------------------------------------------------------------------- FORM check_order USING p_lv_abap_bool p_lv_country p_lv_customer_active p_lv_has_discount CHANGING p_lv_total p_lv_special_customer.
" Ejemplo Correcto FORM check_order USING p_lv_abap_bool p_lv_country p_lv_customer_active p_lv_has_discount CHANGING p_lv_total p_lv_special_customer.
En Conclusión
Me ha quedado algo largo, y eso que he hecho una selección de las recomendaciones que me parecen más interesantes. A pesar de eso, además yo tengo alguna manía más que realizo en mi día a día (no voy a añadir más leña). En entradas posteriores seguiremos hablando de esto pero desde un punto de vista de comprobar la calidad del código existente.
Por último, si solo me tuviese que quedar un un básico, diría: