Ángel Alférez Castroalcaan16

SAP ABAP Developer · Consultor técnico SAP

Los mejores developers SAP son traductores entre negocio y tecnología

No llegué a ABAP desde otro lenguaje, sino desde ocho años de planta en industria cárnica: recepción, gestión de lote, doble unidad de medida, rotación por fecha (criterio FEFO) y trazabilidad de extremo a extremo. Ese conocimiento funcional está convertido aquí en código limpio y testeable: tres proyectos publicados sobre el mismo hilo, recepción → lote → FEFO → alerta de caducidad.

«Cuando un requerimiento habla de entradas de mercancía, de trazabilidad de lote o de diferencias de inventario, no necesito que me lo traduzcan.»

  • 4× SAP Certified 2026
  • ABAP Cloud · CAP · Integration Suite · Fiori
  • La Carlota, Córdoba · remoto, híbrido o presencial cerca de Córdoba

La validación que sale de haber estado delante de la báscula, implementada en P1.

Proyecto 01 · RAP · ABAP Cloud · SAP BTP ABAP Environment

zgr-goods-receipt

Recepción de mercancía con lote y doble unidad de medida

github.com/alcaan16/zgr-goods-receiptABAP 87,9 % · ABAP CDS 12,1 %Licencia MITPublicado 05 · 08 · 2026

Modela la recepción de mercancía en una planta de industria cárnica: verificación contra documento de entrada, registro simultáneo en unidades y kilos (el escenario que SAP cubre con Catch Weight Management), asignación de lote con fecha de caducidad y regularización de discrepancias con motivo.

  • 32tests ABAP Unit
  • 0 / 0errores / avisos ATC
  • 6 + 7 + 4determinations + validations + acciones
  • 10vistas CDS
  • ~1.200líneas de clase de comportamiento

Arquitectura

Entrada de mercancía  (raíz, lock master, draft)
└── Posición              (unidades y peso, esperado y recibido)
    └── Lote                  (lote interno, lote proveedor, caducidad)

Business object RAP managed con draft y 3 niveles de composición. CDS view entities para el modelo, anotaciones UI en metadata extensions separadas. Service definition + service binding OData V4 UI.

Reglas de negocio

Determinations (6)
Número de entrada, número de posición, estado inicial, código de lote interno, fecha de caducidad, desviación y totales de cabecera.
Validations (7)
Proveedor activo, material existente, cantidades y peso obligatorio en doble unidad, plausibilidad del peso medio por pieza, vida útil restante mínima, lote de proveedor obligatorio, cuadre de lotes con la posición.
Acciones (4)
acceptDeviation · postReceipt · blockBatch · releaseBatch, todas con feature control por instancia.

Las dos validaciones que salen de haber estado delante de la báscula

Plausibilidad del peso medio por pieza

Si entran 500 pollos y la báscula marca 6.500 kg, eso son 13 kg por pieza. No es una desviación: es un error de báscula o de conteo, y registrarlo contamina el stock. Ninguna aplicación genérica lo detecta.

Vida útil restante mínima

No basta con que el producto no esté caducado. Se pacta con el proveedor un porcentaje mínimo de vida útil en la entrega: un producto de 8 días que llega con 2 no sirve, porque para cuando pase por producción y llegue al cliente ya no tiene recorrido.

Decisión de diseño: acceptDeviation

acceptDeviation no sobrescribe el peso recibido: sobrescribirlo borraría la evidencia de la diferencia y con ella la base de la reclamación al proveedor. Registra que alguien con criterio aceptó la discrepancia y por qué motivo. El feature control acompaña: la entrada no se puede registrar mientras haya posiciones con desviación sin resolver.

Calidad

Los 32 tests cubren las 4 clases de lógica de negocio: cálculo puro, sin base de datos, sin business object, sin framework. Las 4 clases sobrevivieron sin una línea de cambio a 2 refactorizaciones del modelo de datos, verificable en el historial de commits. ATC sin errores ni avisos; 41 informativos, todos justificados en docs/decisiones-tecnicas.md.

Capturas

Preview del service binding: árbol completo de 3 niveles
01 · Preview del service binding: árbol completo de 3 niveles
Mensaje de error: peso medio por pieza inverosímil
02 · Validación: peso medio por pieza inverosímil
Mensaje de error: vida útil restante insuficiente
03 · Validación: vida útil restante insuficiente
Mensaje de error: cuadre de lotes con la posición
04 · Validación: cuadre de lotes con la posición
Botón «Registrar entrada» deshabilitado por desviación pendiente
05 · Acción deshabilitada: desviación pendiente de resolver
Diálogo de aceptación de desviación con selección de motivo
06 · Aceptar desviación: selección de motivo
Botón «Registrar entrada» habilitado tras resolver la desviación
07 · Acción habilitada tras resolver la desviación
Resultado de los 32 tests de ABAP Unit: todos correctos
08 · ABAP Unit: 32 tests, todos correctos
Resultado del ATC: 0 errores, 0 avisos
09 · ATC: 0 errores, 0 avisos

Proyecto 02 · SAP CAP · Node.js · JavaScript (ES6+) · SQLite

cap-lot-traceability

Trazabilidad de lote con consumo FEFO

Modela la trazabilidad de lote en un proceso de producción: desde el lote recibido de proveedor hasta el lote interno de producto terminado. Cuando la producción diaria necesita más de un lote, el sistema selecciona automáticamente por FEFO (fecha de caducidad más próxima primero) y deja el rastro completo de qué lotes de proveedor componen cada lote interno.

Arquitectura

db/schema.cds                → modelo de datos (8 entidades)
srv/logistica-service.cds    → servicio: proyecciones + 2 operaciones custom
srv/logistica-service.js     → lógica de negocio: handlers y consumo FEFO
srv/logistica-service-ui.cds → anotaciones Fiori (Productos, Pedidos)

Dos bloques en el modelo: catálogo y pedidos (apoyo técnico de CAP) y trazabilidad de lote (LotesProveedor, LotesInternos, ConsumosLote), el caso real.

Lo que demuestra

  • Consumo FEFO: dada una cantidad a producir, selecciona los lotes de proveedor disponibles por fecha de caducidad más próxima primero, reparte entre tantos lotes como haga falta y deja el rastro en ConsumosLote.
  • Atomicidad: si no hay stock suficiente, rechaza antes de escribir nada, sin lotes a medias.
  • Criterio funcional en el modelo: de los 4 productos del catálogo, solo el aceite de oliva (el único perecedero) recibe lotes con caducidad. Un palet no caduca; el modelo no se la fuerza.
  • Verificado con curl, no solo revisado en el código. Los comandos exactos están en el README.

Consumo FEFO · verificado con curl

Producir 100 unidades de Aceite de Oliva 5L con 3 lotes disponibles de distinta caducidad:

LoteCaducidadDisponible antesDisponible después
LOTE-2026-0012027-06-15800 (agotado)
LOTE-2026-0022027-09-016545
LOTE-2026-0032028-01-155050 (sin tocar)

80 + 20 = 100. El orden respeta FEFO.

Modelo de datos

Modelo de datos completo de la trazabilidad de lote
Modelo de datos de la trazabilidad: LotesProveedor, LotesInternos, ConsumosLote

Proyecto 03 · SAP Integration Suite (Cloud Integration) · Node.js / Express

cpi-expiry-alerts

Alertas de caducidad conectadas a la recepción

github.com/alcaan16/cpi-expiry-alertsPublicado 23 · 08 · 2026

Conecta la recepción de mercancía con lote de zgr-goods-receipt con una aplicación externa de alertas de vida útil: toma el dato de lote y caducidad que la recepción ya produce y lo entrega a un sistema que clasifica cada lote como caducado, próximo a caducar u ok.

El caso previsto era «sincronización de maestro de materiales», el ejercicio estándar de cualquier curso de Integration Suite. Se descartó porque P1 no gestiona maestros de material: gestiona entradas de mercancía con lote y caducidad. Este caso mantiene el mismo hilo funcional corriendo por los tres proyectos.

El iFlow

Start Timer → Content Modifier (payload de muestra) → Groovy: filtrar borradores
→ Groovy: mapear formato receptor → Request Reply (HTTPS) → receptor Node/Express
[Exception Subprocess con Groovy: capturar fallo]

El atajo P1 → P3

P1 dejó sin crear el service binding de API (ZAPI_GR_RECEIPT_O4, OData V4 Web API). Ese binding se construyó al arrancar P3, sobre la service definition ya existente de P1, sin tocar nada más: una service definition admite múltiples bindings.

Scripts Groovy

  • 01-filtrar-borradores.groovy: descarta entidades en estado borrador (IsActiveEntity: false).
  • 02-mapea-formato-receptor.groovy: recorre Receipt → Item → Batch y produce un registro plano por lote.
  • 03-capturar-fallo.groovy: dentro del Exception Subprocess, captura cualquier fallo no controlado del flujo principal.

Lo que demuestra, en orden de valor

  1. Exception Subprocess verificado con un fallo real: deteniendo el receptor a propósito, la llamada HTTP falló y la ejecución saltó a la rama de captura. El mensaje terminó como Completed, no como Failed. Es la diferencia entre un flujo que funciona en el camino feliz y uno que se sostiene cuando algo falla.
  2. Criterio de ingeniería documentado: cada limitación (origen de datos, permisos) explica cuál es el bloqueo real y cómo se resolvió sin fingir.
  3. Código real en el repositorio: receiver/ en Node/Express y 3 scripts Groovy, no solo capturas de pantalla.

El fallo capturado · el activo principal

Run Steps con el fallo HTTP y la Exception Subprocess ejecutándose
Run Steps con el fallo HTTP capturado: la Exception Subprocess toma el control
El mensaje marcado como Completed pese al fallo interno
El mensaje termina Completed pese al fallo interno del receptor

Ejecución sin errores y entrega en el receptor

Run Steps de una ejecución sin errores: los 5 pasos del flujo
Run Steps de una ejecución sin errores: los 5 pasos del flujo
Terminal del receptor: los 3 lotes de la muestra con su clasificación
Terminal del receptor: los 3 lotes de la muestra con su clasificación

Stack y certificaciones

Stack técnico y certificaciones

SAP · con proyecto detrás

  • ABAP Cloud
  • RAP
  • CDS view entities
  • OData V4
  • ABAP Unit
  • ATC
  • Clean Core
  • SAP BTP ABAP Environment
  • Eclipse ADT
  • abapGit
  • SAP CAP
  • SAP Integration Suite
  • iFlows
  • Groovy
  • HTTPS adapter
  • SAP Business Application Studio

Fuera de SAP · desarrollo propio

  • Node.js
  • JavaScript
  • Express 5
  • React 19
  • Zustand
  • Vite
  • Astro 5
  • TypeScript
  • Tailwind CSS
  • MongoDB
  • SQLite
  • Docker
  • Git

Lo que no está en la lista, no lo afirmo: todavía no tengo app Fiori/UI5 propia ni he trabajado con iDoc, RFC o ABAP clásico en proyecto. Cada tecnología SAP de arriba tiene un proyecto publicado detrás.

C_FIORD

SAP Certified Associate · Fiori Application Developer

2026

Las tres primeras en formato System-Based Assessment: no son tipo test, se resuelven ejecutando tareas en un sistema SAP en vivo. SAP retiró la opción múltiple del C_ABAPD en la versión 2601 (2026). La de Fiori usa un formato distinto: una entrevista con una IA, de pregunta y respuesta.

Las tres primeras, cada una con un proyecto publicado detrás. La cuarta, Fiori, todavía no tiene proyecto propio: el siguiente paso es una interfaz Fiori Elements sobre P1.

Trayectoria

De la planta al código

  1. 2007-2010

    Experiencia IT inicial

    Dynos · Intarnet

    Trabajo en empresas del sector tecnológico. Titulación oficial: ASI (Administración de Sistemas Informáticos), I.E.S. Gran Capitán, Córdoba.

  2. 2017-2025

    La Carloteña Asados · Responsable de Logística y Control de Stock

    Industria cárnica (pollo, pavo, cerdo) · La Carlota, Córdoba

    • 30.000kg diarios
    • ≈10camiones / día
    • 4personas en el equipo
    • 40-50operarios formados

    Gestión de lote de proveedor y lote interno de fábrica con codificación propia (fecha + secuencial: 202607310198), el escenario que SAP modela con Batch Management. Registro simultáneo en unidades y kilos por palet (320 und / 650 kg): el escenario que SAP cubre con Catch Weight. Control de caducidades y rotación por fecha (criterio FEFO), regularización de inventario por recuento periódico. ERP: LIBRA (Edisa).

    Participé durante ~2 años en la implantación de LIBRA en planta (recepción, deshuesado, manipulado y producción), poniendo en marcha el registro de pesos en recepción y formando a 40-50 operarios en su uso. Es lo que separa a un usuario de ERP de alguien con criterio funcional real.

    Alcance real: gestión de inventario (recepción, lote, regularización). Sin compras ni facturación.

  3. 2026

    Formación SAP y certificaciones

    Experis Academy · 270 horas

    IFCT0097 (ABAP Cloud, 205 h) + IFCT0244 (SAP BTP, 65 h). Cuatro certificaciones SAP Certified Associate obtenidas entre julio y septiembre de 2026. Las tres primeras, en formato System-Based Assessment; la de Fiori, mediante una entrevista con una IA, de pregunta y respuesta.

  4. Ahora

    Portfolio publicado · búsqueda activa

    Tres proyectos SAP publicados sobre el mismo hilo funcional: recepción → lote → FEFO → alerta de caducidad. Busco mi primera posición en desarrollo SAP, por cuenta ajena. Con base en Córdoba, cerca de Sevilla y Málaga: remoto, híbrido o presencial, y viajes a cliente cuando haga falta.

Base técnica previa a SAP

Otros proyectos

Responden a «¿pero sabe programar?» con código propio. La separación por capas de canister-api es la misma idea de modelo + servicio que después aparece en CAP.

canister-api

  • Node.js
  • Express 5

API REST con separación por capas (rutas, controladores, servicios) y CORS. La misma idea de modelo + servicio que después aparece en CAP.

mundoacuatico

  • React 19
  • Zustand
  • React Router 7
  • Vite

Front de tienda con estado global, hooks propios y rutas protegidas. Consume canister-api.

PokeApi

  • Astro 5
  • TypeScript
  • Tailwind CSS
  • pnpm

Sitio estático generado en build sobre una API pública, con rutas por entidad. Mismo stack que este portfolio.

Contacto

Hablemos de entradas de mercancía

Busco mi primera posición en desarrollo SAP, por cuenta ajena. Con base en Córdoba, cerca de Sevilla y Málaga: remoto, híbrido o presencial, y viajes a cliente cuando haga falta.

Descargar CV (ES)Download CV (EN)