Handoff — Endpoint atómico de creación + foliado de factura (SAP B1 Service Layer)¶
Estado: Borrador para handoff a desarrollo local Audiencia: Equipo de desarrollo que consumirá el endpoint desde la aplicación Tipo de componente: Service Layer Script (extensión JavaScript del SAP B1 Service Layer) Última actualización: por completar al finalizar la revisión
Los valores marcados con
«por confirmar»o<PLACEHOLDER>dependen de la instalación y deben validarse contra el entorno real antes de cerrar este documento.
1. Propósito¶
Este endpoint resuelve en una sola petición atómica lo que hoy requeriría tres llamadas secuenciales al Service Layer:
- Crear la factura.
- Consultar la tabla de numeración (
NNM1) por la serie de la factura. - Actualizar la factura para disparar el foliado, asignando los campos de folio en
nullpara que SAP incremente automáticamente elNextFolio.
El objetivo es eliminar los viajes intermedios entre la app y el Service Layer y aplicar el foliado inmediatamente después de la creación, dentro de la misma transacción. Si cualquier paso falla, se revierte todo (no quedan facturas creadas sin foliar ni folios consumidos sin factura).
2. Identificación del endpoint¶
| Atributo | Valor |
|---|---|
| Método HTTP | POST |
| Ruta | /b1s/v1/script/<PARTNER>/<SCRIPT_NAME> — p. ej. /b1s/v1/script/compulandia/facturaFoliada «por confirmar» |
| Base URL (público) | https://sl.compulandia.com.py (expuesto vía Cloudflare) |
| Base URL (interno) | https://sap-linux:50000 |
| Content-Type | application/json |
| Autenticación | Cookie B1SESSION (login nativo del Service Layer) — ver sección 5 |
La ruta del script se compone de
{Partner}/{Script Name}definidos en el archivo.ardde la extensión. Confirmar los nombres definitivos con quien despliega la extensión.
3. Qué requiere tener el sistema (prerrequisitos)¶
Para que el endpoint opere correctamente, el sistema SAP debe cumplir con lo siguiente. Estos puntos son responsabilidad del lado SAP/infraestructura, pero el equipo consumidor debe conocerlos porque condicionan el comportamiento del endpoint.
3.1. Extensión desplegada y asignada¶
- La extensión (Service Layer Script) debe estar importada en el SLD y asignada a la compañía sobre la que se vaya a operar.
- Dev y prod corren como compañías distintas sobre el mismo SLD, por lo que el mismo artefacto debe estar asignado a ambas compañías. No hay despliegue duplicado de código: es el mismo script, asignado a cada compañía.
3.2. Serie de numeración con folio configurado¶
- La factura debe pertenecer a una serie de numeración (
NNM1) que tenga el foliado configurado. - El incremento de
NextFolioenNNM1ocurre únicamente al actualizar el campo de folio de la factura (comportamiento confirmado en pruebas). El endpoint depende de esta mecánica: por eso el paso de creación y el paso de foliado están separados internamente.
3.3. Usuario de Service Layer con permisos¶
- El usuario con el que se abre la sesión debe tener permisos para crear facturas y modificar el folio en la compañía destino.
3.4. Datos maestros consistentes¶
- Los datos que se envíen en la factura (socio de negocio, ítems, almacén, etc.) deben existir y ser válidos en la compañía destino. Una validación fallida del lado de SAP aborta toda la transacción.
4. Flujo interno (contexto)¶
El equipo consumidor no necesita implementar estos pasos: el endpoint los ejecuta server-side dentro de una única transacción. Se documentan solo para dar contexto del comportamiento.
POST /b1s/v1/script/<PARTNER>/<SCRIPT_NAME>
│
▼
startTransaction()
│
├─ 1. Crear factura (Invoices.add) → obtiene DocEntry y Series
│
├─ 2. Consultar NNM1 por la serie de la factura
│
├─ 3. PATCH de la factura con:
│ { "FolioPrefixString": null, "FolioNumber": null }
│ → SAP incrementa NextFolio y asigna el folio
│
▼
commitTransaction() (rollback automático ante cualquier fallo)
│
▼
Respuesta con la factura ya foliada
Características transaccionales: - Atómico: cualquier error revierte la transacción completa. - Límite de operaciones: el Service Layer Scripting permite máximo 10 operaciones por transacción. Este flujo usa 3, dentro del límite.
5. Autenticación y contexto de compañía¶
El Service Layer (en su forma nativa) admite login por cookie B1SESSION. El consumidor
debe autenticarse antes de invocar el endpoint:
POST /b1s/v1/Login
Content-Type: application/json
{
"CompanyDB": "<COMPANY_DB>",
"UserName": "<USER>",
"Password": "<PASSWORD>"
}
La respuesta incluye la cookie B1SESSION (y ROUTEID), que debe enviarse en las llamadas
posteriores al endpoint.
Punto clave para dev/prod: la diferenciación de ambiente se hace por el CompanyDB del
login, no por la URL del endpoint (que es idéntica en ambos). La sesión queda ligada a la
compañía, y el script opera siempre sobre la compañía de esa sesión. Esto garantiza el
aislamiento de datos entre dev y prod.
| Ambiente | CompanyDB |
|---|---|
| Desarrollo | <COMPANY_DB_DEV> «por confirmar» |
| Producción | <COMPANY_DB_PROD> «por confirmar» |
6. Contrato de la petición (request)¶
Headers
| Header | Valor |
|---|---|
Content-Type |
application/json |
Cookie |
B1SESSION=<token>; ROUTEID=<route> |
Body — datos de la factura. La estructura sigue el objeto Invoices del Service Layer.
Ejemplo representativo (los campos exactos deben confirmarse con el lado SAP):
{
"CardCode": "<SOCIO_DE_NEGOCIO>",
"DocDate": "2026-06-30",
"DocDueDate": "2026-06-30",
"Series": "<SERIE_NUMERACION>",
"DocumentLines": [
{
"ItemCode": "<ITEM>",
"Quantity": 1,
"WarehouseCode": "<ALMACEN>"
}
]
}
A confirmar con el lado SAP: campos obligatorios mínimos, manejo de
Series, UDFs requeridos (p. ej. campos de sucursal), e impuestos/localización Paraguay. El equipo consumidor no debe enviarFolioPrefixString/FolioNumber: el foliado lo resuelve el endpoint internamente.
7. Contrato de la respuesta (response)¶
Éxito — el endpoint devuelve la representación de la factura ya creada y foliada.
HTTP/1.1 200 OK (o 201 Created, «por confirmar» según implementación del script)
Content-Type: application/json
{
"DocEntry": 1234,
"DocNum": 5678,
"Series": "<SERIE>",
"FolioPrefixString": "<PREFIJO_ASIGNADO>",
"FolioNumber": 9012,
"...": "resto de la representación de la factura"
}
El folio asignado (
FolioPrefixString/FolioNumber) viene en el cuerpo de la respuesta, por lo que no es necesaria una consulta adicional para conocerlo.
8. Manejo de errores¶
El script propaga errores como excepciones con su código HTTP correspondiente. Ante cualquier error la transacción se revierte por completo: no queda factura creada ni folio consumido.
| Código HTTP | Significado típico | Acción del consumidor |
|---|---|---|
400 |
Payload inválido / validación de negocio fallida (ítem, socio, serie) | Corregir datos y reintentar |
401 |
Sesión inválida o expirada | Re-autenticar (nuevo Login) y reintentar |
404 |
Recurso referenciado no encontrado (p. ej. dato maestro) | Validar datos maestros |
500 |
Error interno del script / Service Layer | Registrar y escalar a SAP/infra |
El cuerpo de error sigue el formato estándar del Service Layer:
{
"error": {
"code": 600,
"message": { "lang": "es-py", "value": "<descripción del error>" }
}
}
Recomendación: loguear
error.codeyerror.message.valuecompletos del lado del consumidor; son la principal fuente de diagnóstico ya que el debugging del script es limitado.
9. Consideraciones de integración para el consumidor¶
- Idempotencia: el endpoint no es idempotente. Cada llamada exitosa crea una factura y consume un folio. Ante incertidumbre por timeout, no reintentar a ciegas: verificar primero si la factura se creó antes de reenviar.
- Timeouts y reintentos: definir un timeout acorde a la latencia del Service Layer (incluye el salto por Cloudflare en el acceso público). Si hay timeout sin respuesta, tratar como estado desconocido, no como fallo.
- Sesión: reutilizar la cookie
B1SESSIONmientras esté vigente; renovarla ante401. - Ambiente: asegurarse de apuntar al
CompanyDBcorrecto en elLogin. Un error aquí escribe en la compañía equivocada. - Concurrencia de foliado: el folio es un recurso secuencial. Bajo alta concurrencia, el comportamiento del incremento depende de la serialización del lado SAP; coordinar pruebas de carga con infra antes de producción.
10. Supuestos y puntos a confirmar (auditable)¶
Lista explícita de lo que en este documento es supuesto o queda pendiente de validar, para que no se asuma como definitivo:
- Nombre definitivo de
Partner/Script Name(y por ende la ruta del endpoint). CompanyDBexactos de dev y prod.- Estructura definitiva del payload de la factura (campos obligatorios, UDFs, impuestos PY).
- Código de respuesta de éxito definitivo (
200vs201) según la implementación del script. - Forma exacta de la consulta a
NNM1por serie (si el resultado se usa como insumo del PATCH o solo para validación posterior). - Comportamiento del incremento de
NextFoliobajo concurrencia, validado en pruebas de carga. - Política de exposición: si el consumidor accede por la URL pública (Cloudflare) o solo interna.
11. Referencias¶
- Working with SAP Business One Service Layer — secciones: Batch Operations (3.10), JavaScript Extension / Scripting (3.20), Deployment (3.20.8), Transaction API (3.20.5.5).
- Tabla
NNM1(series de numeración /NextFolio). - Objeto
Invoicesdel Service Layer (metadata de la instancia).