- DP_EntradasAbiertas (v3) lee OpenInvQty en lugar de OpenQty. - publicar: la release no contiene enlaces simbólicos (copia real de @dp/shared). - DEPLOY.md y CLAUDE.md actualizados. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
299 lines
21 KiB
Markdown
299 lines
21 KiB
Markdown
# CLAUDE.md
|
|
|
|
Aplicación web **Devolución a Proveedores** para SAP Business One. Reemplaza al addon
|
|
.NET Framework (`../SolucionLibros/`), que **se abandona**: todo pasa a Angular + NestJS.
|
|
`../SolucionLibros/` queda solo como referencia de la lógica original — **no modificarlo**.
|
|
|
|
## Qué hace el proceso
|
|
|
|
Genera **Devoluciones de mercancías** (ORPD, ObjType 21) enlazadas a sus **Entradas de
|
|
mercancías por compra** (OPDN, ObjType 20), a partir de un listado de artículos y
|
|
cantidades pegado desde Excel. Cada ejecución se guarda en el UDO `LIB_ODEV`
|
|
(cabecera `@LIB_ODEV`, líneas `@LIB_DEV1`).
|
|
|
|
Pasos de la UI (decididos):
|
|
|
|
1. **Pegar**: ItemCode + cantidad desde Excel (con el botón *Pegar desde el portapapeles* o
|
|
`Ctrl/Cmd+V` en el cuadro). Se valida el stock (`OITW.OnHand`) del almacén elegido. No guarda.
|
|
2. **Procesar**: reemplaza a "Selección" del addon. Asignación FIFO contra líneas abiertas
|
|
de Entradas de mercancías **del almacén elegido**, ordenadas por `DocDate`. Genera filas
|
|
Padre (`F`, artículo) y Hijo (`S`, una por Entrada consumida). El usuario marca o desmarca
|
|
qué líneas Hijo devolver.
|
|
3. **Crear devoluciones**: agrupa las líneas marcadas sin `TargetEntry` por proveedor y
|
|
las parte en lotes de `U_PrintingLines` líneas (11 por defecto). Crea una Devolución por
|
|
lote y graba `U_TargetType`/`U_TargetEntry` en las líneas.
|
|
4. **Descargar PDF**: por cada Devolución, se pide el PDF de la Guía de despacho (DTE tipo 52)
|
|
al web service SOAP de BES, usando las credenciales de `@DTE_CONFC`. Opción de unir todos
|
|
los PDF en uno.
|
|
|
|
## Decisiones tomadas (no volver a discutir)
|
|
|
|
- Solo se crean **Devoluciones** (ObjType 21), no Solicitudes de devolución. Solo se cargan
|
|
las series de Devoluciones.
|
|
- `U_Status` de cabecera **eliminado**. El estado usa el `Status` estándar del UDO (`O`/`C`).
|
|
- Se usan `U_TipoDespacho` y `U_IndicadorTraslado` en `@LIB_ODEV`. Se envían a la Devolución
|
|
como `U_BFE_TipoDespacho` / `U_BFE_IndTraslado`.
|
|
- Cantidades y referencias son **enteros** (`db_Numeric`): `Quantity`, `OnHand`, `OpenQty`,
|
|
`AllocatedQty`, `BaseEntry`, `BaseLine`, `BaseRef`, `TargetEntry` y `U_Series`.
|
|
- Producción en **HANA**; ambiente de pruebas en **MSSQL**. Toda consulta SQL debe tener las
|
|
dos variantes, según `DB_TYPE`.
|
|
- Sin control de concurrencia: **solo puede haber una planificación abierta**. Para crear
|
|
una nueva, todas las anteriores tienen que estar cerradas.
|
|
- Después de Procesar, el usuario elige qué líneas devolver. **Una línea con `TargetEntry`
|
|
ya no se puede desmarcar** (ver `puedeCambiarSeleccion` en `libs/shared`).
|
|
- La planificación se **cierra a mano** (`POST /planificaciones/:id/cerrar`).
|
|
- **Reprocesar** (botón *Rehacer FIFO* del Detalle) solo vale para una planificación **abierta y sin
|
|
Devoluciones**. Las filas de un UDO no se pueden quitar por Service Layer, así que se crea una nueva
|
|
(heredando la cabecera) y, **después** de crearla, se cierra la anterior (si el cierre falla se avisa
|
|
para cerrarla a mano).
|
|
- **Crear devoluciones**: resultado **parcial por documento**. Cada Devolución se crea aparte; las
|
|
buenas graban `U_TargetType`/`U_TargetEntry`, las fallidas `U_ErrCode`/`U_ErrMsg` y se reintentan.
|
|
- **Consultas SQL** por `SQLQueries` del Service Layer (no hay conexión directa a la BD). La API
|
|
crea/actualiza `DP_Stock` y `DP_EntradasAbiertas` sola (variante según `DB_TYPE`). El analizador
|
|
SQL del Service Layer **no admite `FORMAT`** y SAP reescribe el `SqlText`: al cambiar el SQL hay
|
|
que subir `version` en `sql-queries.definitions.ts`. Los parámetros van entre comillas simples.
|
|
`DP_EntradasAbiertas` (v3) lee la cantidad abierta de `PDN1.OpenInvQty` (no `OpenQty`); el campo
|
|
de usuario `U_OpenQty` del UDO conserva su nombre.
|
|
- **Listado** de planificaciones **paginado en SAP** (`$top/$skip/$inlinecount`, OData v3 del SL v1),
|
|
más nueva primero, con filtros por estado, almacén y rango de fechas. Por defecto 20 por página,
|
|
máximo 100. En la pantalla: botones **Atrás** / **Siguiente**; filtros y página quedan en la URL.
|
|
- **PDF**: no se usa el paquete `soap`; `bes-soap.ts` arma el sobre y lee la respuesta a mano y `BesClient`
|
|
lo envía con axios (SOAPAction `http://tempuri.org/Consulta_TXTDTE`). Credenciales y URL salen de
|
|
`U_DTE_CONFC` y **nunca** se registran ni se devuelven al navegador. Solo se consulta con el
|
|
`FolioNumber` de la Devolución: **si todavía no tiene folio no se llama a BES** y esa Devolución informa
|
|
"todavía no tiene folio" (el addon usaba el `DocNum` como respaldo; se descartó porque podría traer el DTE
|
|
de otro documento). Unir con `pdf-lib`; un fallo en una Devolución no impide las demás.
|
|
- Transporte en la Devolución (ORPD): `RutTransporte→U_BFE_RutTrasporte` (sic), `Patente→U_BFE_Patente`,
|
|
`RutChofer→U_BFE_RutChofer`, `NombreChofer→U_BFE_NombreChofer`. **ORPD no tiene UDF para fechas
|
|
ni hora de salida/llegada**: solo se guardan en `@LIB_ODEV`.
|
|
- **Despliegue en Windows**: un solo servicio. La API sirve también la web compilada (mismo origen: sin
|
|
CORS y con la cookie `SameSite=strict`), con **HTTPS directo en Node** (`HTTPS_PFX_PATH` o
|
|
`HTTPS_KEY_PATH`+`HTTPS_CERT_PATH`) y redirección opcional de HTTP (`HTTP_REDIRECT_PORT`). El servicio
|
|
lo administra **NSSM** (decisión del usuario; se evaluó WinSW y no se lo consideró lo bastante estable);
|
|
nginx no es necesario. NSSM 2.24 estable puede no arrancar en Windows recientes: usar la 2.24-101. `npm run publicar` arma `release/devolucion-proveedores/` (API + web + solo dependencias de
|
|
producción, ~55 MB, **sin enlaces simbólicos**: `@dp/shared` va como copia real, porque la API lo
|
|
importa al ejecutarse y un enlace no sobrevive a copiar de Mac a Windows). Guía completa: `deploy/windows/DEPLOY.md`.
|
|
- **Logs**: la aplicación **no escribe logs a archivo**; usa el `Logger` de Nest por consola. En
|
|
producción NSSM captura la salida y la rota a los 10 MB (no limita cuántos archivos conserva: hay que
|
|
limpiar los viejos). Con `NO_COLOR=1` el log sale sin códigos de
|
|
color. Solo se registran errores 4xx/5xx, fallos o lentitud del Service Layer y eventos de negocio.
|
|
- Aplicación web **independiente**. Login con el usuario de SAP B1 vía **Login del Service Layer**.
|
|
- Metadatos (UDT/UDF/UDO) definidos en **JSON** con formato del Service Layer. La web tiene la
|
|
pantalla **Configuración → Metadatos** con el botón **Reconstruir**, y NestJS los crea.
|
|
Los cambios que borran datos (campo con tipo distinto o campo sobrante) solo se hacen con
|
|
autorización explícita.
|
|
- **Después de cada login** se verifica que existan las tablas, los campos y el UDO. Si
|
|
falta algo, se redirige a Configuración → Metadatos. El login tiene una casilla **"Verificar
|
|
los metadatos de SAP al ingresar"** (activa por defecto; se recuerda en `localStorage`).
|
|
Desactivada, el guard omite la verificación; Configuración → Metadatos siempre verifica.
|
|
|
|
## Estructura
|
|
|
|
```
|
|
devolucion-proveedores-web/ npm workspaces
|
|
├── libs/shared/ @dp/shared tipos + lógica de dominio pura (ESM, se compila a dist/)
|
|
│ └── src/
|
|
│ ├── models/ auth, metadata, planificacion, catalogos (catálogos, páginas, PDF)
|
|
│ └── domain/ portapapeles.ts (parseo Excel), fifo.ts (FIFO, consolidación)
|
|
├── apps/api/ NestJS 12 ESM ("type": "module"), imports con extensión .js
|
|
│ ├── .env(.example)
|
|
│ └── src/
|
|
│ ├── config/ configuration.ts (lee .env)
|
|
│ ├── service-layer/ ServiceLayerClient (axios, cola por sesión), SessionStore (memoria)
|
|
│ ├── auth/ login/logout/me/info, SessionGuard global + @Public()
|
|
│ ├── sql-queries/ SqlQueriesService + definiciones (DP_Stock, DP_EntradasAbiertas)
|
|
│ ├── catalogos/ almacenes, series, valores UDF
|
|
│ ├── planificaciones/ service, controller, dto, udo.mapper (puro, con tests)
|
|
│ ├── pdf/ bes-soap (puro), BesClient, PdfDteService (descarga y unión)
|
|
│ ├── metadata/ analyzer (puro), service, controller
|
|
│ │ └── definitions/ user-tables.json, user-fields.json, user-objects.json,
|
|
│ │ external-dependencies.json ← fuente de verdad
|
|
│ ├── health/
|
|
│ ├── http-exception.logger.ts filtro global: deja en el log todo error 4xx/5xx
|
|
│ ├── web-estatico.ts sirve el build de Angular, fallback a index.html, cabeceras de seguridad
|
|
│ └── https.ts lectura del certificado y redirección HTTP → HTTPS
|
|
├── scripts/publicar.mjs arma la carpeta de despliegue (release/, ignorada por git)
|
|
├── deploy/windows/ NSSM: instalar/desinstalar-servicio.ps1, DEPLOY.md
|
|
└── apps/web/ Angular 22 standalone, signals, zoneless, CSS (no SCSS)
|
|
└── src/app/
|
|
├── core/ auth.service, metadata.service, planificaciones.service,
|
|
│ guards, auth.interceptor, http-error
|
|
├── layout/ shell.ts (barra y navegación), stepper.ts (4 pasos)
|
|
└── pages/
|
|
├── login/ con la casilla de verificar metadatos
|
|
├── metadatos/ Configuración → Metadatos
|
|
└── planificaciones/ listado (filtros + paginación) · nueva/ (pasos 1-2) · detalle/ (pasos 3-4)
|
|
```
|
|
|
|
### API (prefijo `/api`)
|
|
|
|
| Método | Ruta | Descripción |
|
|
|---|---|---|
|
|
| GET | `/health` | público |
|
|
| GET | `/auth/info` | público: CompanyDB y DB_TYPE configurados |
|
|
| POST | `/auth/login` | `{userName, password}`: Login en el Service Layer y cookie httpOnly `dp_sid` |
|
|
| POST | `/auth/logout` | Logout en el Service Layer |
|
|
| GET | `/auth/me` | usuario de la sesión |
|
|
| GET | `/metadata/status` | compara las definiciones contra la base SAP |
|
|
| POST | `/metadata/rebuild` | `{permitirDestructivos: boolean}`: crea y corrige |
|
|
| GET | `/catalogos` | almacenes, series de Devoluciones (con la por defecto), valores de `BFE_TipoDespacho`/`BFE_IndTraslado` |
|
|
| GET | `/catalogos/almacenes` | solo almacenes (filtros del listado) |
|
|
| GET | `/planificaciones?status=&whsCode=&desde=&hasta=&pagina=&tamano=` | **una página** (`{items,total,pagina,tamano,totalPaginas}`), más nueva primero; filtros y salto en SAP. `tamano` máx. 100, por defecto 20 |
|
|
| GET | `/planificaciones/abierta` | la abierta (`{abierta: null}` si no hay; siempre JSON) |
|
|
| GET | `/planificaciones/:docEntry` | detalle: cabecera y líneas |
|
|
| POST | `/planificaciones/pegar` | `{whsCode, texto}`: valida Excel contra stock. No guarda |
|
|
| POST | `/planificaciones` | procesa: FIFO + guarda en `LIB_ODEV`. 409 si ya hay una abierta |
|
|
| PATCH | `/planificaciones/:id/cabecera` | serie, fecha, despacho, traslado, transporte |
|
|
| PATCH | `/planificaciones/:id/lineas/:lineId` | `{applied}`. 409 si la línea ya tiene `TargetEntry` |
|
|
| POST | `/planificaciones/:id/devoluciones` | crea las Devoluciones de las líneas marcadas |
|
|
| POST | `/planificaciones/:id/reprocesar` | rehace el FIFO: crea una planificación nueva y cierra la anterior. Solo si está **abierta y sin Devoluciones** (409 si no) |
|
|
| POST | `/planificaciones/:id/pdf` | `{unir?: boolean}`: pide a BES el PDF de la Guía de despacho (DTE 52) de cada Devolución; devuelve los archivos en base64 y el resultado por Devolución |
|
|
| POST | `/planificaciones/:id/cerrar` | cierra la planificación |
|
|
|
|
La sesión del Service Layer (`B1SESSION`/`ROUTEID`) vive en el servidor; el navegador solo
|
|
tiene `dp_sid`. `SessionStore` es en memoria: alcanza para una sola instancia de la API y **se
|
|
pierde al reiniciar la API** (hay que volver a iniciar sesión).
|
|
|
|
### Metadatos (definitions/*.json)
|
|
|
|
- **Tablas:** `LIB_ODEV` (bott_Document) y `LIB_DEV1` (bott_DocumentLines).
|
|
- **UDO:** `LIB_ODEV` (boud_Document), hija `LIB_DEV1`. CanFind/CanClose/CanCancel = tYES,
|
|
CanDelete = tNO, CanLog = tYES (`ALIB_ODEV`), sin formulario por defecto. Columnas de búsqueda:
|
|
`DocEntry`, `U_WhsCode`, `U_DocDate`.
|
|
- **Campos de `@LIB_ODEV`:** WhsCode, DocDate, Series (num), ObjType, PrintingLines (num),
|
|
TipoDespacho, IndicadorTraslado, RutTransporte, RutChofer, NombreChofer, FechaSalida,
|
|
HoraSalida (st_Time), FechaLlegada, Patente.
|
|
- **Campos de `@LIB_DEV1`:** LineType (F/S), ItemCode, ItemDescription, Quantity, OnHand, Status,
|
|
BaseType, BaseEntry, BaseLine, BaseRef, BaseDocDate, OpenQty, AllocatedQty, Applied (Y/N),
|
|
TargetType, TargetEntry, CardCode, CardName, ErrCode, ErrMsg.
|
|
- **Dependencias externas** (solo se verifican, no se crean): `OPDN.U_DOT_TipoRecepcion`,
|
|
`OINV.U_BFE_TipoDespacho`, `OINV.U_BFE_IndTraslado` y la tabla `@DTE_CONFC`.
|
|
|
|
## Preparar el entorno (otro computador)
|
|
|
|
1. **Node 22 LTS** o superior (`node -v`).
|
|
2. **Red con Fortinet** (inspección SSL): npm falla con `SELF_SIGNED_CERT_IN_CHAIN`.
|
|
Exportar antes de usar npm u ng:
|
|
```sh
|
|
export NODE_EXTRA_CA_CERTS="/ruta/a/fortinet-root.crt" # está en ../fortinet-root.crt
|
|
# alternativa, si el certificado está en el llavero de macOS:
|
|
export NODE_OPTIONS=--use-system-ca
|
|
export NG_CLI_ANALYTICS=false # si no, `ng` puede quedar esperando el prompt
|
|
```
|
|
3. Instalar y configurar:
|
|
```sh
|
|
npm install
|
|
cp apps/api/.env.example apps/api/.env # completar SL_URL, SL_COMPANY_DB, DB_TYPE
|
|
```
|
|
Variables del `.env` de la API: `PORT` (3000), `WEB_ORIGIN` (CORS), `SL_URL` (con `/b1s/v1`),
|
|
`SL_COMPANY_DB`, `SL_REJECT_UNAUTHORIZED` (`false` si el certificado es autofirmado), `DB_TYPE`
|
|
(`HANA`/`MSSQL`) y `COOKIE_SECURE` (`true` solo con HTTPS). **El usuario y la contraseña de SAP no van
|
|
en el `.env`**: se escriben en el login. Solo para producción: `HTTPS_PFX_PATH`/`HTTPS_PFX_PASSPHRASE` o
|
|
`HTTPS_KEY_PATH`/`HTTPS_CERT_PATH`, `HTTP_REDIRECT_PORT` y `WEB_DIST_DIR` (opcional).
|
|
4. Desarrollo, en dos terminales:
|
|
```sh
|
|
npm run dev:api # compila @dp/shared y levanta NestJS en :3000
|
|
npm run dev:web # compila @dp/shared y levanta Angular en :4200 (proxy /api → :3000)
|
|
```
|
|
5. Verificación:
|
|
```sh
|
|
npm test # shared + api + web
|
|
npm run test:e2e -w api
|
|
npm run lint -w api
|
|
npm run build
|
|
npm run publicar # carpeta de despliegue en release/ (ver deploy/windows/DEPLOY.md)
|
|
```
|
|
|
|
Reglas:
|
|
- `@dp/shared` se consume **compilado** (`dist/`). Si se cambia, ejecutar `npm run build:shared`
|
|
**y reiniciar `ng serve`**: Vite sirve una copia vieja y la página falla con "does not provide an
|
|
export named ..." (los tests no lo detectan).
|
|
- En la API, los tipos que aparecen en firmas con decoradores se importan con `import type`
|
|
(por `isolatedModules` + `emitDecoratorMetadata`). Los DTO (clases) sí se importan como valor.
|
|
- Al cambiar código del backend con `start:dev` la API se reinicia y **se pierden las sesiones**.
|
|
- Los tests del frontend no usan zone.js: tras un `flush` hay que esperar con
|
|
`await new Promise((r) => setTimeout(r))` y luego `fixture.detectChanges()` (`whenStable` no basta).
|
|
- Para ver la UI sin la extensión de Chrome se puede abrir Chrome sin cabeza con
|
|
`--remote-debugging-port` y manejarlo por DevTools Protocol (`WebSocket` de Node 22).
|
|
|
|
## Estado al 2026-10-12
|
|
|
|
**Hecho y verificado contra el Service Layer real (SBOLibros, MSSQL):**
|
|
- Login, Metadatos y **Reconstruir** (creación de tablas, campos y UDO desde cero).
|
|
- `libs/shared`: modelos y dominio portado del .NET. 14 tests.
|
|
- `apps/api`: Service Layer, autenticación, metadatos, catálogos, planificaciones y PDF. 81 tests
|
|
unitarios + 6 e2e (incluye la cookie de sesión: `HttpOnly`, `Secure`, `SameSite=Strict`), lint limpio. Prueba de extremo a extremo manual OK: pegar → procesar (FIFO) →
|
|
cabecera (fecha/hora) → marcar/desmarcar → crear Devolución (ORPD con base en OPDN) → `TargetEntry`
|
|
grabado → cerrar. **Varios proveedores** OK contra SAP (una planificación con 4 líneas generó 3
|
|
Devoluciones, con un proveedor reuniendo dos líneas). Las reglas 409 (una sola abierta, línea con
|
|
destino, cerrada) OK. **Listado
|
|
paginado y filtrado** (total, saltos, estado/almacén/fechas) OK. **PDF** contra BES (certificación)
|
|
con 4 Devoluciones reales: individuales y unificado (3 páginas) OK.
|
|
- `apps/web`: login, guards, Metadatos y Planificaciones completas (listado con filtros y paginación,
|
|
Nueva, Detalle con crear devoluciones, Rehacer FIFO, PDF y cerrar). 38 tests. Verificado en Chrome
|
|
real (sin cabeza): login, listado con filtros, selector de almacenes, validación de pegado y la
|
|
descarga de PDF del Detalle.
|
|
|
|
**Aprendido del Service Layer real:**
|
|
- **Una sesión no admite peticiones simultáneas**: las procesa en serie y cada una espera ~7 s tras
|
|
la anterior (seis en paralelo = ~40 s; una a una = ~40 ms). `ServiceLayerClient.request` las
|
|
**encola por sesión**; no lo saltes con otro cliente HTTP. Avisa en el log si una tarda > 2 s.
|
|
- `CanFind = tYES` exige `UserObjectMD_FindColumns`; sin ellas SAP lo deja en `tNO` en silencio.
|
|
- `GET UserFieldsMD` informa los campos de hora como `db_Numeric/st_Time` (el analizador lo normaliza).
|
|
- `PATCH` de `LIB_DEV1Collection` actualiza las filas por `LineId` sin tocar las demás; **no se pueden
|
|
quitar filas** de un UDO.
|
|
- Los campos numéricos sin llenar del UDO vuelven como `0`: el mapeo los trata como `null`.
|
|
- `POST /LIB_ODEV(n)/Close` cierra el UDO. El UDO no se puede borrar (`CanDelete = tNO`).
|
|
- Si no hay resultado, el Service Layer responde cuerpo vacío: por eso `/planificaciones/abierta`
|
|
devuelve siempre un JSON (`{abierta: null}`).
|
|
|
|
**Sin verificar:**
|
|
- **HANA**: el addon .NET ya funcionaba en HANA, y las consultas son un port de las suyas, así que
|
|
su lógica está probada. Lo que no se ha probado es **cómo las recibe el Service Layer de HANA**
|
|
(`SQLQueries`: su analizador es más estricto que el `DoQuery` del addon; en MSSQL rechazó `FORMAT`) y los
|
|
tres cambios respecto al addon: el filtro por almacén (`PDN1.WhsCode`), la columna `PDN1.OpenInvQty`
|
|
y los parámetros con nombre (`:item`, `:whs`). Tampoco el paginado (`$inlinecount`/`odata.count` es de `/b1s/v1`; en `/b1s/v2` sería
|
|
`$count`) ni los tipos que HANA informa en los metadatos.
|
|
- **Reprocesar** solo con tests (no contra SAP).
|
|
- Fallo parcial al crear Devoluciones (solo se probó el caso feliz). El corte en lotes de
|
|
`U_PrintingLines` líneas está probado con tests del algoritmo portado del addon, no contra SAP.
|
|
- El `PATCH` de Reconstruir sobre un UDO ya existente con columnas de búsqueda.
|
|
- Paginación con varias páginas en la interfaz (hoy hay pocas planificaciones; sí está probada con la
|
|
API real y con tests de la pantalla).
|
|
- Recorrido con clics de **Procesar** en un navegador real.
|
|
- **PDF en la base de pruebas**: las Devoluciones de `SBOLibros` no tienen `FolioNum`, así que ahora su
|
|
descarga informa el error de folio. El PDF contra BES se probó antes del cambio, usando el `DocNum`.
|
|
Para repetirlo hace falta una Devolución con folio (la que emite el addon de facturación electrónica).
|
|
- **Despliegue en Windows**: la carpeta publicada se probó en un Mac (API con HTTPS autofirmado, web
|
|
servida por la API, rutas de Angular, 404, cabeceras, redirección 301, log sin colores). **No se ha
|
|
ejecutado en Windows**: los `.ps1` solo pasaron la comprobación de sintaxis y la lista de comandos de
|
|
NSSM que generan (`-SoloMostrar`); falta instalar el servicio de verdad. Las banderas de la cookie de sesión están comprobadas en un
|
|
test e2e; solo falta verlo en un navegador real sobre HTTPS (iniciar sesión en el sitio desplegado).
|
|
- **Estilos:** son CSS porque, en el Mac con macOS 12, el compilador nativo de Sass exige
|
|
macOS 14 o superior. En Sequoia se puede volver a SCSS si se prefiere.
|
|
|
|
## Siguientes pasos
|
|
|
|
1. **Validar en HANA** (ver "Sin verificar"): `DB_TYPE=HANA`, Reconstruir, repetir la prueba de extremo a extremo.
|
|
2. Probar los casos sin verificar (fallo parcial y reprocesar contra SAP).
|
|
3. **Probar el despliegue en un servidor Windows** (de pruebas) siguiendo `deploy/windows/DEPLOY.md`. El
|
|
botón de pegar desde el portapapeles solo funciona en `localhost` o HTTPS.
|
|
4. Archivar `../SolucionLibros/` cuando HANA esté validado (ninguna carpeta está bajo `git`).
|
|
|
|
## Preguntas abiertas para el usuario
|
|
|
|
1. ¿Se agregan UDF de fecha/hora de salida y llegada a la Devolución (ORPD)? Hoy no existen.
|
|
2. Tamaño de `U_TipoDespacho`/`U_IndicadorTraslado` en `@LIB_ODEV` (10) frente a ORPD (1 y 2).
|
|
|
|
## Referencias en el addon .NET (`../SolucionLibros/DevolucionProveedores/`)
|
|
|
|
Ya está todo portado; sirve para comparar resultados (sobre todo al validar en HANA).
|
|
|
|
- `FormularioDevolucionProveedores.Negocio.cs`: parseo, consultas OnHand/FIFO, consolidación.
|
|
- `FormularioDevolucionProveedores.Botones.cs`: Crear devoluciones (BOM y `Add`), descarga de PDF.
|
|
- `FormularioDevolucionProveedores.Bom.cs`: guardado del UDO (`GeneralService`) y BOM de la Devolución.
|
|
- `WebServices/ConsultaDTE.cs`, `WebServices/PdfUtils.cs`: SOAP BES y unión de PDF.
|
|
- `ESPECIFICACION.md`: especificación original del proceso.
|
|
- `bin/x64/Debug/UserFields.xml` (UTF-16): versión XML anterior de los metadatos, ya
|
|
reemplazada por los JSON de `apps/api/src/metadata/definitions/`.
|