Files
devolucion_proveedores/apps/web
georgeandClaude Sonnet 5.5 287b187c14 Aplicación web de Devolución a Proveedores para SAP Business One
Reemplaza al addon .NET Framework (SolucionLibros). Genera Devoluciones de mercancías
enlazadas a sus Entradas por compra a partir de un listado pegado desde Excel.

- libs/shared (@dp/shared): modelos y lógica de dominio pura (FIFO, consolidación por
  proveedor, parseo del portapapeles), portada del addon.
- apps/api (NestJS): cliente del Service Layer con cola por sesión, login con la sesión de
  SAP, metadatos (UDT/UDF/UDO) y botón Reconstruir, catálogos, planificaciones (pegar,
  procesar, reprocesar, marcar líneas, crear Devoluciones, cerrar), listado paginado con
  filtros y descarga de PDF de la Guía de despacho desde BES. Sirve también la web
  compilada, con HTTPS opcional.
- apps/web (Angular): login, Configuración → Metadatos y Planificaciones (listado,
  nueva, detalle).
- deploy/windows y scripts/publicar.mjs: despliegue como servicio de Windows con WinSW.

Verificado contra el Service Layer de SQL Server. Sin probar aún: SAP HANA y la
instalación del servicio en Windows (ver CLAUDE.md, sección "Sin verificar").

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-13 08:09:07 -05:00
..

Web — Devolución a Proveedores

Frontend en Angular 22 (componentes standalone, signals, sin zone.js, CSS) de la aplicación Devolución a Proveedores para SAP Business One. Consume la API NestJS de ../api.

La documentación general del proyecto (decisiones, flujo, estado) está en ../../CLAUDE.md. Este archivo cubre solo cómo ejecutar y mantener la web.

Puesta en marcha

Desde la raíz del monorepo (devolucion-proveedores-web/), con la API ya levantada:

npm install
npm run dev:web      # compila @dp/shared y levanta Angular en http://localhost:4200

ng serve redirige /api a http://localhost:3000 (ver src/proxy.conf.json), así que no hace falta configurar CORS en desarrollo. Con Fortinet, exportar antes NODE_OPTIONS=--use-system-ca y NG_CLI_ANALYTICS=false.

Importante: @dp/shared se consume compilado. Si lo cambia, ejecute npm run build:shared y reinicie ng serve: Vite sirve una copia vieja y la página falla con "does not provide an export named …". Los tests no lo detectan.

Scripts

Comando Qué hace
ng serve / npm start Servidor de desarrollo con recarga.
ng build Compila a dist/web.
ng test Tests (Vitest + jsdom). Para una sola pasada: npx ng test --watch=false.

En producción

La web no se despliega por separado: ng build genera dist/web/browser y la API (NestJS) la sirve junto con /api, por HTTPS y en el mismo origen. Por eso las llamadas son siempre relativas (/api/...). npm run publicar (en la raíz) arma la carpeta de despliegue; ver ../../deploy/windows/DEPLOY.md.

Pantallas

Ruta Pantalla
/login Usuario y contraseña de SAP B1, con la casilla "Verificar los metadatos de SAP al ingresar".
/planificaciones Listado con filtros (estado, almacén, fechas) y paginación (Atrás / Siguiente, filas por página). Los filtros y la página quedan en la URL.
/planificaciones/nueva Pasos 1 y 2: elegir almacén y fecha, pegar el listado desde Excel (botón Pegar desde el portapapeles o Ctrl/Cmd+V), validar y procesar (FIFO). Con ?reemplaza=<id> rehace una planificación.
/planificaciones/:docEntry Pasos 3 y 4: datos de las Devoluciones y transporte, grilla Padre/Hijo con casillas, Crear devoluciones, Rehacer FIFO, Descargar PDF y Cerrar planificación.
/configuracion/metadatos Estado de tablas, campos y objeto de usuario en SAP, y el botón Reconstruir.

Flujo de rutas: authGuard exige sesión; metadataGuard verifica los metadatos una vez por sesión y, si falta algo, lleva a Configuración → Metadatos (se omite si el usuario desmarcó la casilla del login). Una respuesta 401 en cualquier llamada devuelve al login.

Estructura

src/app/
├── core/          servicios HTTP (auth, metadata, planificaciones), guards, interceptor y errores
├── layout/        shell (barra superior) y stepper de los 4 pasos
└── pages/
    ├── login/
    ├── metadatos/
    └── planificaciones/   listado · nueva/ · detalle/

Cada página tiene su .ts, .html y .css; los tests (*.spec.ts) están junto a lo que prueban. La lógica de negocio pura (FIFO, qué líneas se pueden marcar, consolidación por proveedor) se importa de @dp/shared, la misma que usa la API.

Cosas que conviene saber

  • El navegador solo conoce la cookie dp_sid; la sesión de SAP vive en el servidor y se pierde si la API se reinicia (habrá que volver a iniciar sesión).
  • Descarga de PDF: la API devuelve los archivos en base64; la pantalla arma Blobs y enlaces (URL.createObjectURL). Con un solo archivo lo descarga directo; con varios deja un enlace por archivo.
  • Pegar desde el portapapeles usa navigator.clipboard.readText(): solo funciona en localhost o HTTPS, y el navegador pide permiso. Si lo niega, se puede pegar a mano dentro del cuadro de texto.
  • Estilos en CSS, no SCSS: en macOS 12 el compilador nativo de Sass exige macOS 14 o superior. Las variables de color y espaciado están en src/styles.css.
  • Tests sin zone.js: tras un flush de HttpTestingController hay que esperar con await new Promise((r) => setTimeout(r)) y llamar a fixture.detectChanges(); whenStable() no alcanza para las promesas de firstValueFrom.

Diagnóstico rápido

Síntoma Causa probable
Pantalla en blanco con "does not provide an export named …" en la consola @dp/shared cambió y ng serve quedó con la copia vieja. Reiniciarlo.
Vuelve al login sin avisar Sesión de SAP vencida o API reiniciada.
http proxy error: /api/… ECONNREFUSED en la terminal La API no está levantada (o se está reiniciando).
La lista de almacenes sale vacía Mirar el recuadro rojo de la pantalla: indica qué llamada falló.