SAP CAP – Uso de Draft o modo borrador

SAP CAP - Uso de Draft o modo borrador

Introducción

SAP CAP – Uso de Draft o modo borrador, En algún momento, al desarrollar una aplicación, todos hemos enfrentado la necesidad de almacenar datos de manera temporal hasta que estén totalmente completos. Por ejemplo, imagine que va al banco para abrir una cuenta bancaria. Los formularios que estas entidades requieren para registrar a un nuevo cliente suelen ser bastante extensos, lo que puede llevar tiempo tanto para la institución como para el cliente que los completa en línea. Ahora, suponga que, por alguna razón, no cuenta con toda la información solicitada y necesita esperar hasta el día siguiente para completarla. Entonces, ¿será necesario volver a llenar toda la información desde el principio? En este caso, podrían darse dos situaciones: al día siguiente, los datos que ingresó aún están guardados, o, por el contrario, tendría que volver a completarlos desde cero.

Sin embargo, este tipo de procesos largos que involucran mucho tiempo puede ser que se deban almacenar de forma temporal hasta cierto punto, es decir, que no estén en las tablas persistentes de la base de datos hasta que el usuario final lo decida. En este contexto, este tipo de situaciones se pueden controlar con CAP de manera muy eficiente con tan solo habilitar la anotación @odata.draft.enabled. Incluso, tampoco es necesario implementar alguna lógica adicional para realizar operaciones CRUD, a menos que se requiera alguna acción muy específica.

Fundamentos básicos

Draft Support

Según la documentación oficial, SAP Fiori admite sesiones de edición con estados de borrador almacenados en el servidor, para que los usuarios puedan interrumpir y continuar más tarde, posiblemente desde diferentes lugares y dispositivos. CAP, así como los elementos de SAP Fiori, brindan soporte listo para usar borradores. Recomendamos utilizar siempre el borrador cuando su aplicación necesite la entrada de datos por parte de los usuarios finales.

En resumen, un borrador es una versión temporal de una entidad comercial que aún no se ha guardado explícitamente como versión activa.

Los borradores se utilizan:

  • Para conservar los cambios no guardados si se interrumpe una actividad de edición, permitiendo a los usuarios reanudar la edición más tarde.
  • Para evitar la pérdida de datos si una aplicación finaliza inesperadamente.
  • Como mecanismo de bloqueo para evitar que varios usuarios editen el mismo objeto al mismo tiempo y para que los usuarios sepan cuando hay cambios sin guardar realizados por otro usuario.

¿Cómo funciona el botón Guardar / Aplicar?

Para comprender un poco mejor este proceso, vea la Figura 1.1

Figura 1.1.
  1. En una página de objeto, el usuario elige Editar.
  2. El sistema crea una versión borrador del objeto.
  3. El usuario realiza cambios en la versión borrador del objeto y navega a una página de detalles. Cuando el usuario elige Aplicar, los cambios se aplican al borrador.
  4. Cuando el usuario elige Guardar, los cambios se guardan en la versión activa del objeto.

¿Cómo habilitar el borrador?

Para habilitar el borrador para una entidad expuesta por un servicio, simplemente anótelo con @odata.draft.enabled como en este ejemplo:

Esto quiere decir, que el borrador se debe aplicar a la proyección y no en la entidad original, ya que de esta manera sólo la proyección manejaría los estados del borrador. Por otro lado, la anotación @odata.draft.enabled = null indica que la proyección no debe manejar los estados del borrador, incluso si la entidad original lo tiene habilitado.

Ejemplo demostrativo

Para poder comprender con mayor facilidad el concepto del draft lo ideal sería plantear el siguiente escenario, defina una entidad llamada Employees y haga una relación de uno a muchos con Contactos, quedando el código de la siguiente manera, recuerde que debe crear un archivo llamado schema.cds dentro de la carpeta db.

Una vez listas las entidades con sus relaciones específicas, es necesario que realice las proyecciones de las dos entidades. Para ello cree dentro de la carpeta srv un archivo llamado: service.cds y copie el siguiente código:

Como resultado final debería tener las siguientes vistas:

Vista previa:

View: EmployeesSet

View: ContactsSet

Ahora si vemos a nivel de base de datos, podremos notar que se generan las siguientes vistas y tablas.

En la sección Tables:

Verá que aparece el namespace: com_logaligroup seguido de los nombres de las entidades.

En la sección Views:

Verá que aparece el nombre del servicio: LogaliGroup seguido de los nombres de las proyecciones.

De momento, el draft no ha sido habilitado y cualquier registro pasaría directamente a las tablas persistentes, como lo podemos ver a continuación:

Podemos hacer GET a las respectivas entidades para ver los registros creados:

GET – EmployeesSet

GET – ContactsSet

De igual manera, es posible ver el registro en las tablas persistentes, como se muestra a continuación:

com_logaligroup_Employees

com_logaligroup_Contacts

Hasta ahora, vemos que todo funciona con toda normalidad y no hay presencia de ninguna tabla intermedia, los registros se fueron directamente a las tablas persistentes. Entonces, es momento de habilitar el draft para la proyección raíz, que en este caso le corresponde a la vista padre: EmployeesSet. Recuerde que no colocaremos el draft en la entidad raíz si no en la proyección raíz. Para ello, agregue el siguiente código:

Veamos ahora, que tenemos a nivel de base de datos:

Podemos notar que en la sección Tables: se generaron nuevas tablas en base a las proyecciones de empleados y los contactos pero con la terminación drafts.

LogaliGroup_ContactsSet_drafts

LogaliGroup_EmployeesSet_drafts

y adicional tenemos presencia de otra nueva tabla: DRAFT_DraftAdministrativeData así como una nueva proyección: LogaliGroup_DraftAdministrativeData. Estas últimas son utilizada para controlar el ciclo de vida de los datos temporales. Veamos a continuación la estructura que ambas tienen:

El campo más importante para tener en cuenta mientras se trabaja con borradores, sería el DraftUUID el mismo contendrá el ID único de todos los registros que estarán presentes en modo: edición. El resto de los campos es para controlar aspectos de seguridad básico, como la fecha de creación, así como el registro del usuario.

Retomando nuevamente los registros de ambas entidades procedamos a crear nuevamente un nuevo empleado pero con el draft activo. En teoría, los datos no deberían llegar directamente a la tabla persistente si no en las tablas borradores. Para ello, realizamos una nueva inserción de datos como se muestra a continuación:

Como puede notar en la imagen, la respuesta del servidor fue exitosa pero automáticamente aparecen tres nuevos campos:

HasActiveEntity: indica si un borrador tiene versión activa.

  • true: existe una versión activa del registro.
  • false: no existe una versión activa del registro, lo que podría significar que es un borrador nuevo que aún no ha sido publicado.

HasDraftEntity: indica si un registro activo tiene un borrador pendiente.

  • true: existe un borrador para este registro activo.
  • false: no existe un borrador para este registro activo.

IsActiveEntity: Indica si la versión está activa (sin draft) o si está en la versión borrador (con draft).

  • true: el registro es la versión activa de la entidad.
  • false: el registro es una versión de borrador.

Sin embargo, al querer visualizar los datos con el método GET no lograremos ver ningun registro.

GET – EmployeesSet

GET – ContactsSet

Al realizar la consulta en cada una de las proyecciones tal como muestran las imágenes no visualizará nada y esto es debido a que el registro se encuentra en la tabla draft y no en la tabla persistente. Esto lo puede verificar viendo las tablas drafts.

LogaliGroup_EmployeesSet_drafts

LogaliGroup_ContactsSet_drafts

Como puede notar en ambas imágenes los registros están pero en las tablas drafts y al momento de hacer el GET no es posible visualizar los datos al menos que indiquemos que la entidad esté en modo edición. Es decir, que es necesario colocar el campo IsActiveEntity = false, acompañado del ID del Empleado y/o Contacto.

GET – EmployeesSet with IsActiveEntity = false

GET – ContactsSet with IsActiveEntity = false

Entonces, hasta no hacer pasar el registro a las tablas persistente no será posible visualizar los datos. Para ello debe tener la siguiente URL en donde se hace uso de la acción: draftActivete, que permitirá el paso de IsActiveEntity: false a true.

Como podrá ver en la URL, al final hay una acción (draftActivate) que está vinculada a la proyección EmployeesSet. Por lo que al llamar a la misma con dicha acción, los datos pasan a las tablas persistentes y ahora si es posible visualizar los datos desde el GET porque el campo IsActiveEntity cambio a true, como se muestra a continuación:

GET – EmployeesSet

GET – ContactsSet

Al obtener los datos en las tablas persistentes ya no es posible visualizar los mismos en la tablas drafts.

Tablas Persistentes – com_logaligroup_Employees

Tablas Persistentes – com_logaligroup_Contacts

Tablas borradores – LogaliGroup_EmployeesSet

Tablas borradores – LogaliGroup_Contacts

Conclusión

Las tablas de drafts en CAP son una característica que permite la edición temporal de datos antes de su confirmación final. Su principal objetivo es proporcionar una experiencia de edición en la que los usuarios puedan realizar cambios sin que estos se reflejen inmediatamente en los datos persistidos en la base de datos principal.

  • Cuando un usuario edita un registro, se crea una copia temporal de ese registro en una tabla de draft. Los cambios se aplican a esta copia, permitiendo que los usuarios revisen y modifiquen antes de confirmar.
  • Para cada proyección con habilitación de drafts, se crea automáticamente una tabla de draft con el nombre del servicio pero con un sufijo que indica que es una tabla de draft (_DRAFTS).
  • Los datos en la tabla de drafts no son visibles en la tabla original hasta que se realiza la confirmación final (Acción: draftActivate).
  • Una vez que el usuario finaliza las modificaciones, puede optar por confirmar (IsActiveEntity = true) los cambios. En ese momento, los datos del draft se copian a la tabla persistente, reemplazando o agregando los registros correspondientes.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *