Envío de actividad al CRM
I . OBJETO DEL EVOLUTIVO:
Enviar reporte de actividad de los diversos actores de LaabPro (alumnos, profesores, tutores, administradores …), para la actualización de registros del módulo de CRM de Expedientes Académicos (Nombre de API: Fichas_de_programa)
Dicho módulo consta de los siguientes campos:







Progreso académico es un “subformulario” del módulo Expedientes Académicos cuyo nombre de API es: Progreso_Acad_mico1. Viene a ser como una tabla en la que cada módulo tiene un registro con los siguientes campos: Orden del módulo, Módulo (nombre del módulo), Examen, Caso / CPD, Foro, Calificación media del módulo, Contenido Visualizado, Módulo liberado y Comentarios del módulo.
NOMBRE DE API
Subformulario Progreso Académico: Progreso_Acad_mico1
- Calificaci_n_media_m_dulo
- Caso_CPD
- Contenido_visualizado
- Examen
- Foro
- M_dulo
- M_dulo_liberado
- Orden_M_dulo
II . REQUISITOS
Los requisitos solicitados consisten en la actualización de los siguientes campos en el transcurso de la actividad de los distintos actores que interactúan en la plataforma LaabPro:
1º) - Estado de Alumno en plataforma.
2º) - Primera conexión en plataforma.
3º) – Última conexión en Plataforma.
4º) - Progreso académico del alumno (subformulario de progreso académico):
- Modulo num liberado.
- Calificación examen de cada módulo.
- Calificación del caso.
- Calificación del foro.
- Calificacion media.
- % de contenido visualizado.
- Check: módulo liberado.
5º) - TFM (Fuera del subformulario).
III . REFERENCIA DE DATOS EN LAABPRO.
En la tabla mdl_local_academic_transcripts almacenaremos un código único de expediente referenciado por id de grupo y id de alumno. En los casos de uso de creación de un nuevo expediente se insertará en el registro correspondiente y en los casos de uso de “cambio de promoción” se hará una actualización del campo “groupid”, ya que por cada curso, el alumno sólo puede estar en un grupo y cuando se realiza tal cambio, desde el gestor de contenidos, se solicita explícitamente si se desea que los datos que componen las calificaciones de cada alumno pasen o no de un grupo a otro.
ESTRUCTURA DE LA TABLA mdl_local_academic_transcripts: Su estructura viene determinada por la siguiente DDL
CREATE TABLE mdl_local_academic_transcripts ( id bigint(20) NOT NULL AUTO_INCREMENT, userid bigint(20) NOT NULL, groupid bigint(20) NOT NULL, transcriptcode varchar(45) NOT NULL, PRIMARY KEY (id)) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPACT COMMENT='Table to store user academic transcript codes';IV . SERVICIOS EXTERNOS DE EXPEDIENTES ACADEMICOS:
Hay que dar de alta en Moodle estos 2 servicios:
1) - local_servicerefactor_register_academic_transcript
Servicio que registra en DB un código de Expediente Académico.
PARAMS:
-wstoken: [token_autenticación]
-moodlewsrestformat: json
-wsfunction: local_servicerefactor_register_academic_transcript
-useremail: [email_de_usuario]
-groupid: [id_del_grupo]
-transcriptcode: [codigo_de_expediente]
RETURN:
{ "status": 200, "code": 0, "message": "Success"}El usuario no está dado de alta en el grupo
{ "status": 404, "code": 2, "message": "User is not enroled in this course."}Usuario no encontrado
{ "status": 404, "code": 1, "message": "User not found"}Error que se produce por un token de autenticació n invá lido
{ "exception": "moodle\_exception", "errorcode": "invalidtoken", "message": "Invalid token - token not found"}Error que se produce cuando existe una clave duplicada en DB de usuario y de grupo
{ "status": 404, "code": 3, "message": "User already has a transcript code in this group."}2) - local_servicerefactor_get_user_academic_transcript_code
Servicio que obtiene el código registrado en LaabPro del Expediente Académico de un alumno.
PARAMS:
-wstoken: [token_autenticación]
-moodlewsrestformat: json
-wsfunction: local_servicerefactor_get_user_academic_transcript
-useremail: [email_de_usuario]
-groupid: [id_del_grupo]
RETURN:
{ "status": 200, "code": 0, "message": "Success", "body": { "transcriptcode": "ACEXP000003"* }}No encuentra el expediente para este alumno en este grupo
{ "status": 404, "code": 3, "message": "No transcript was found for this student in this group.", "body": []}Error que se produce por un token de autenticació n inválido
{ "exception": "moodle_exception", "errorcode": "invalidtoken", "message": "Invalid token - token not found"}Estos servicios son los que se usarán externamente, ya sea desde los ecommerce o desde cualquier artefacto que deba registrar en Moodle una referencia con un código único para refenciar cada Expediente Academíco.
V . FUCIONALIDAD.
En todos aquellos servicios que registren la actividad de los distintos actores de LaabPro, se enviarán los datos a Zoho mediante un webhook que recibirá la siguiente estructura de datos, en formato JSON.
El webhook se configurará en el El apartado Plugins→Local plugins →Service refactor settings

Dentro de la administración de Moodle (Site administration).
Para el envío de los datos y la actividad especificados en los requisitos, mediante el mencionado webhook, se usan instancias de las clases definidas en el package zoho del plugin “moodle_plugin_servicerefactor” alojado en el repositorio de GitHub.

Como ya he comentado, por cada caso de uso (Visualización de contenidos, envío de exámenes, correción de casos por el tutor, envíos de TFM, corrección de TFM, liberación de módulos, Entrada de los alumnos a los cursos …), se enviarán mediante un webhook de Zoho flow los datos pertinentes, en un JSON con la siguiente estructura:
{ cambioPromocion : "No", calificacionDefensaTFM : null, entregaTFM : null, codigo : null, idGrupoLaabPro : null, moduloLiberado : null, calificacionTFM : null, ultimoAcceso : null, ordenModulo : null, evaluacionCaso : null, primerAcceso : null, notaExamen : null, contenidoVisualizadoModulo : null, calificacionMediaModulo : null, evaluacionForo : null, estadoAlumnoPlataforma : null, nombreModulo : null, fechaEntregaTFM : null
}En Zoho, se actualizarán los campos con valor distinto de null, según los distintos casos de uso
VI. Casos de Uso
1. Matriculación de un alumno
Cuando un alumno se matricula en un curso que requiere crear un expediente académico, se hará una llamada al servicio local_servicerefactor_register_academic_transcript que registrará en LaabPro, el código del expediente académico, tal como se describe en el apartado IV.
2. Expediente no registrado
Si el expediente no está registrado en LaabPro, no se realiza ningún envío.
3. Contenido visualizado
Se recoge la actividad de los alumnos mediante el patrón Observer, implementado con las APIs del core de Moodle, sobre el evento \core\event\course_module_completion_update. Este evento se activa cuando se sobrepasa un porcentaje de visualización de un vídeo o cuando se accede a un contenido estático (como un PDF).
Se envía un webhook con este JSON:
{ "cambioPromocion": "No", "calificacionDefensaTFM": null, "entregaTFM": null, "codigo": "EXPMAST000001", "idGrupoLaabPro": null, "moduloLiberado": null, "calificacionTFM": null, "ultimoAcceso": null, "ordenModulo": 2, "evaluacionCaso": null, "primerAcceso": null, "notaExamen": null, "contenidoVisualizadoModulo": 17, "calificacionMediaModulo": null, "evaluacionForo": null, "estadoAlumnoPlataforma": null, "nombreModulo": "Nuevos modelos de atención y de comunicación", "fechaEntregaTFM": null}Donde:
codigo: Código del expediente académico para su posterior localización en el módulo de expedientes.ordenModulo: Orden del módulo correspondiente.nombreModulo: Nombre del módulo.contenidoVisualizadoModulo: Porcentaje de contenidos visualizados.
4. Envío de exámenes
Al finalizar un examen, se llama al servicio local_servicerefactor_get_attempt_review, que corrige el examen y obtiene la nota.
Se envía el siguiente JSON a Zoho:
{ "cambioPromocion": "No", "calificacionDefensaTFM": null, "entregaTFM": null, "codigo": "EXPMAST000001", "idGrupoLaabPro": null, "moduloLiberado": null, "calificacionTFM": null, "ultimoAcceso": null, "ordenModulo": 1, "evaluacionCaso": null, "primerAcceso": null, "notaExamen": "1.15", "contenidoVisualizadoModulo": null, "calificacionMediaModulo": null, "evaluacionForo": null, "estadoAlumnoPlataforma": null, "nombreModulo": null, "fechaEntregaTFM": null}Donde:
codigo: Código del expediente académico.ordenModulo: Orden del módulo.notaExamen: Nota obtenida en el examen.
5. Cambio de grupo
Cuando un administrador de LaabPro cambia un alumno de grupo, se invoca la función local_contentdata_change_group_user del webservice de Moodle.
Se envía a Zoho:
{ "cambioPromocion": "Si", "calificacionDefensaTFM": null, "entregaTFM": null, "codigo": "EXPMAST000001", "idGrupoLaabPro": 538, "moduloLiberado": null, "calificacionTFM": null, "ultimoAcceso": null, "ordenModulo": null, "evaluacionCaso": null, "primerAcceso": null, "notaExamen": null, "contenidoVisualizadoModulo": null, "calificacionMediaModulo": null, "evaluacionForo": null, "estadoAlumnoPlataforma": null, "nombreModulo": null, "fechaEntregaTFM": null}Donde:
codigo: Código del expediente académico.cambioPromocion: Indica si se trata de un cambio de grupo.idGrupoLaabPro: ID del nuevo grupo asignado.
6. Último acceso
Cada vez que un alumno accede a un curso, se llama al servicio local_servicerefactor_group_get_course_user_groups, que envía el siguiente payload:
{ "cambioPromocion": "No", "calificacionDefensaTFM": null, "entregaTFM": null, "codigo": "EXPCORTO00002", "idGrupoLaabPro": null, "moduloLiberado": null, "calificacionTFM": null, "ultimoAcceso": "2025-07-30", "ordenModulo": null, "evaluacionCaso": null, "primerAcceso": "2025-03-30", "notaExamen": null, "contenidoVisualizadoModulo": null, "calificacionMediaModulo": null, "evaluacionForo": null, "estadoAlumnoPlataforma": null, "nombreModulo": null, "fechaEntregaTFM": null}Donde:
codigo: Código del expediente académico.ultimoAcceso: Último acceso del alumno.primerAcceso: Primer acceso del alumno.
7. Lista de módulos abiertos y cerrados
Cada vez que un alumno accede a un curso, por cada módulo se envía este payload con los datos de los módulos abiertos y cerrados:
{ "cambioPromocion": "No", "calificacionDefensaTFM": null, "entregaTFM": null, "codigo": "EXPMAS0000001", "idGrupoLaabPro": null, "moduloLiberado": 1, "calificacionTFM": null, "ultimoAcceso": null, "ordenModulo": 7, "evaluacionCaso": null, "primerAcceso": null, "notaExamen": null, "contenidoVisualizadoModulo": null, "calificacionMediaModulo": null, "evaluacionForo": null, "estadoAlumnoPlataforma": null, "nombreModulo": "Ética y valores en la dirección de la clínica", "fechaEntregaTFM": null}Donde:
codigo: Código del expediente académico.nombreModulo: Nombre del módulo.ordenModulo: Orden del módulo.moduloLiberado: 1 si el módulo está liberado, 0 si no lo está.