92 lines
4.9 KiB
Markdown
92 lines
4.9 KiB
Markdown
# 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`](../api/README.md).
|
||
|
|
|
||
|
|
La documentación general del proyecto (decisiones, flujo, estado) está en
|
||
|
|
[`../../CLAUDE.md`](../../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:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
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`](../../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 `Blob`s 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ó. |
|