Documentación de Historia de Usuario¶
1. Información General¶
- ID: US-001
- Título: Impresión de Documentos
- Épica asociada: Módulo de Impresiones
- Proyecto / App: OMS Backend
- Fecha de creación: 2025-03-23
- Última actualización: 2025-03-23
- Autor: -
- Estado:
[x] Backlog[ ] En progreso[ ] En revisión[ ] Completado
2. Historia de Usuario¶
Como usuario del sistema (vendedor, técnico, administrativo), quiero imprimir un documento (pedido, factura) presionando un botón de imprimir. con posibilidad de cambiar el layout y la impresora, para entregar una copia física al cliente o para archivo.
3. Descripción¶
El usuario necesita imprimir documentos del sistema (pedidos, facturas) de forma directa. Cada tipo de documento tiene un layout asignado por defecto (configurado en .env). La impresora se obtiene automáticamente del UserDefaultGroup del usuario en SAP, según el tipo de impresión (ticket, papel o etiqueta).
Tipos de Impresora¶
| Tipo | Campo UDF en SAP | Uso |
|---|---|---|
| Ticket | U_PrinterTicket |
Facturas y pedidos en formato ticket (80mm) |
| Papel | U_PrinterPaper |
Documentos en hoja carta/A4 |
| Etiqueta | U_PrinterLabel |
Etiquetas de productos |
Nota: Los campos UDF almacenan el ID numérico de la impresora en PrintNode.
Integración con Servicios Externos¶
El sistema se integra con tres servicios para completar el flujo de impresión:
SAP Service Layer (Puerto 50000)¶
- Función: Obtiene la configuración del usuario (UserDefaultGroup) con las impresoras asignadas
- Autenticación: Sesión con credenciales de sistema
- Endpoint:
GET /b1s/v2/UserDefaultGroups('{code}')
SAP API Gateway (Puerto 60000)¶
- Función: Genera el PDF del documento usando Crystal Reports
- Autenticación: Sesión con credenciales de sistema (usuario/contraseña)
- Output: PDF codificado en base64
- Endpoint:
POST /rs/v1/ExportPDFData
PrintNode¶
- Función: Envía el PDF a impresoras físicas remotas
- Autenticación: API Key
- Input: PDF en formato base64 (compatible directo con el output del API Gateway)
- Content-Type:
pdf_base64 - Endpoint:
POST https://api.printnode.com/printjobs
Flujo de Integración¶
┌──────────┐ ┌──────────────┐ ┌───────────────────┐ ┌─────────────────┐ ┌───────────┐ ┌───────────┐
│ Frontend │────▶│ OMS Backend │────▶│ SAP Service Layer │ │ SAP API Gateway │ │ PrintNode │────▶│ Impresora │
└──────────┘ └──────────────┘ └───────────────────┘ └─────────────────┘ └───────────┘ └───────────┘
│ │ │ ▲
│ 1. Get UserDefaults │ │ │
│─────────────────────▶│ │ │
│ │ │ │
│ 2. U_PrinterTicket │ │ │
│◀─────────────────────│ │ │
│ │ │
│ 3. Request PDF (layoutCode) │ │
│───────────────────────────────────────────────▶│ │
│ │ │
│ 4. PDF (base64) │ │
│◀───────────────────────────────────────────────│ │
│ │
│ 5. Enviar PDF (base64) + printerId │
│────────────────────────────────────────────────────────────────────▶│
│ │
│ 6. printJobId │
│◀────────────────────────────────────────────────────────────────────│
4. Actores Involucrados¶
| Actor | Rol |
|---|---|
| Usuario | Vendedor, técnico o administrativo que necesita imprimir documentos |
| Sistema OMS | Orquesta la generación del PDF y el envío a impresora |
| SAP API Gateway | Genera el PDF con Crystal Reports |
| PrintNode | Servicio de impresión en la nube |
5. Criterios de Aceptación¶
- [ ] CA-01: El usuario puede imprimir un documento presionando un botón (ticket o papel)
- [ ] CA-02: El sistema usa el layout por defecto configurado en .env según el tipo de documento
- [ ] CA-03: El sistema obtiene la impresora del UserDefaultGroup del usuario en SAP
- [ ] CA-04: El sistema genera el PDF usando SAP API Gateway
- [ ] CA-05: El sistema envía el PDF a PrintNode con el ID de la impresora del usuario
- [ ] CA-06: El usuario recibe confirmación del envío con el ID del trabajo de impresión
- [ ] CA-07: Si el usuario no tiene impresora configurada, el sistema muestra lista de impresoras disponibles para seleccionar
- [ ] CA-08: Si PrintNode falla, el sistema muestra error descriptivo
6. Escenarios (Gherkin / BDD)¶
Escenario: Imprimir documento en ticket
Dado que el usuario está viendo un documento (pedido o factura)
Y el usuario tiene configurada una impresora de ticket en su UserDefaultGroup (U_PrinterTicket)
Cuando el usuario presiona "Imprimir Ticket"
Entonces el sistema obtiene el layout por defecto del .env
Y obtiene el printerId de U_PrinterTicket del usuario
Y genera el PDF con el layout
Y envía el PDF a PrintNode
Y muestra el mensaje "Documento enviado a imprimir" con el ID del trabajo
Escenario: Imprimir documento en papel
Dado que el usuario está viendo un documento (pedido o factura)
Y el usuario tiene configurada una impresora de papel en su UserDefaultGroup (U_PrinterPaper)
Cuando el usuario presiona "Imprimir Papel"
Entonces el sistema obtiene el layout por defecto del .env
Y obtiene el printerId de U_PrinterPaper del usuario
Y genera el PDF con el layout
Y envía el PDF a PrintNode
Y muestra el mensaje "Documento enviado a imprimir" con el ID del trabajo
Escenario: Usuario sin impresora configurada
Dado que el usuario está viendo un documento
Y el usuario NO tiene configurada impresora de ticket en su UserDefaultGroup
Cuando el usuario presiona "Imprimir Ticket"
Entonces el sistema muestra la lista de impresoras disponibles
Y el usuario selecciona una impresora
Y el sistema envía el documento a la impresora seleccionada
Escenario: Error de conexión con PrintNode
Dado que el usuario está viendo un documento
Y el usuario tiene configurada una impresora válida
Y PrintNode no está disponible
Cuando el usuario presiona "Imprimir"
Entonces el sistema muestra el mensaje "Error al conectar con el servicio de impresión"
7. Wireframes / Mockups¶
Opción 1: Botones directos en la vista del documento
┌─────────────────────────────────────────────────────────────────┐
│ Pedido #15629 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Cliente: Juan Pérez │
│ Fecha: 2025-03-23 │
│ Total: $1,500.00 │
│ │
│ ... (detalle del documento) ... │
│ │
├─────────────────────────────────────────────────────────────────┤
│ │
│ [🖨️ Imprimir Ticket] [🖨️ Imprimir Papel] │
│ │
└─────────────────────────────────────────────────────────────────┘
Confirmación de impresión (toast/snackbar):
┌─────────────────────────────────────────────────────────┐
│ ✓ Documento enviado a imprimir (Job ID: 789456) │
└─────────────────────────────────────────────────────────┘
8. Flujo de Usuario¶
Flujo con impresora configurada (default)¶
- El usuario accede a un documento (pedido o factura)
- El usuario presiona "Imprimir Ticket" o "Imprimir Papel"
- El sistema:
- Obtiene el layout por defecto del tipo de documento (.env)
- Obtiene la impresora del UserDefaultGroup del usuario
- Genera el PDF con el layout
- Envía el PDF a la impresora
- El sistema muestra confirmación con el ID del trabajo de impresión
Flujo sin impresora configurada¶
- El usuario accede a un documento (pedido o factura)
- El usuario presiona "Imprimir Ticket" o "Imprimir Papel"
- El sistema detecta que no tiene impresora configurada para ese tipo
- El sistema muestra lista de impresoras disponibles en PrintNode
- El usuario selecciona una impresora
- El sistema genera el PDF y lo envía a la impresora seleccionada
- El sistema muestra confirmación con el ID del trabajo de impresión
9. Reglas de Negocio¶
- RN-01: Cada tipo de documento tiene un layout asignado por defecto (configurado en .env)
- RN-02: La impresora se obtiene del UserDefaultGroup del usuario en SAP
- RN-03: Existen 3 tipos de impresora: Ticket (
U_PrinterTicket), Papel (U_PrinterPaper), Etiqueta (U_PrinterLabel) - RN-04: Los campos UDF almacenan el ID numérico de la impresora en PrintNode
- RN-05: La cantidad de copias es siempre 1 (no configurable en esta versión)
- RN-06: Si el usuario no tiene impresora asignada en su UserDefaultGroup, puede seleccionar una de las impresoras disponibles en PrintNode
10. Requisitos Técnicos / Notas de Implementación¶
Endpoints del Backend (OMS)¶
| Método | Endpoint | Descripción |
|---|---|---|
| GET | /api/printers |
Lista todas las impresoras disponibles en PrintNode |
| GET | /api/printers/user |
Obtiene las impresoras configuradas del usuario (desde UserDefaultGroups) |
| POST | /api/print |
Envía documento a imprimir |
Configuración Requerida (.env)¶
# SAP Service Layer (ya existente)
SAP_SERVICE_LAYER_URL=https://sap-linux:50000/b1s/v2
SAP_SL_USER=usuario_sistema
SAP_SL_PASSWORD=password_sistema
SAP_COMPANY_DB=nombre_empresa
# Layouts por defecto (Crystal Reports)
REPORT_LAYOUT_ORDER=RCRI0026
REPORT_LAYOUT_INVOICE=RCRI0029
REPORT_LAYOUT_PAYMENT=RCRI0030
REPORT_LAYOUT_DELIVERY=RCRI0031
REPORT_LAYOUT_CREDIT_NOTE=RCRI0032
# Layouts pendientes de crear en SAP
# REPORT_LAYOUT_SERVICE_CALL=RCRI00XX
# REPORT_LAYOUT_QUOTATION=RCRI00XX
# REPORT_LAYOUT_INVENTORY_TRANSFER=RCRI00XX
# REPORT_LAYOUT_LABEL=RCRI00XX
# PrintNode
PRINTNODE_API_KEY=tu_api_key_aqui
Configuración Requerida en SAP (UDFs)¶
Los siguientes campos deben crearse en la entidad UserDefaultGroups:
| Campo UDF | Tipo | Descripción |
|---|---|---|
U_PrinterTicket |
Int32 | ID de impresora PrintNode para tickets (80mm) |
U_PrinterPaper |
Int32 | ID de impresora PrintNode para papel (carta/A4) |
U_PrinterLabel |
Int32 | ID de impresora PrintNode para etiquetas |
Ejemplo de UserDefaultGroup con impresoras configuradas:
{
"Code": "VAVI",
"Name": "Ventas Aviadores",
"U_PrinterTicket": 75290979,
"U_PrinterPaper": 75242714,
"U_PrinterLabel": null
}
En este ejemplo: - Tickets: EPSON TICKETS ST - AVIADORES (75290979) - Papel: HP LaserJet Pro MFP M127fn (75242714) - Etiquetas: No configurada
Consulta para obtener impresoras del usuario:
GET https://sap-linux:50000/b1s/v2/UserDefaultGroups('UD01')?$select=Code,U_PrinterTicket,U_PrinterPaper,U_PrinterLabel
SAP API Gateway - Generación de PDF¶
URL Base: Se deriva de SAP_SERVICE_LAYER_URL cambiando el puerto a 60000
Autenticación: Login con credenciales de sistema
POST https://sap-linux:60000/login
Content-Type: application/json
{
"CompanyDB": "nombre_empresa",
"UserName": "usuario_sistema",
"Password": "password_sistema"
}
Respuesta: Cookies de sesión (Session, ROUTEID)
Generación de PDF:
POST https://sap-linux:60000/rs/v1/ExportPDFData?DocCode=RCRI0026
Content-Type: application/json
Cookie: Session=xxx; ROUTEID=.node1
[
{ "name": "Dockey@", "type": "xsd:string", "value": [["33008"]] },
{ "name": "FolioNum@", "type": "xsd:string", "value": [["15629"]] }
]
Respuesta: PDF en formato base64 (string)
PrintNode - Envío a Impresora¶
URL Base: https://api.printnode.com
Autenticación: Basic Auth con API Key
Authorization: Basic {base64(apiKey:)}
Listar Impresoras:
GET https://api.printnode.com/printers
Authorization: Basic {credentials}
Respuesta:
[
{
"id": 75290979,
"name": "EPSON TICKETS ST - AVIADORES",
"description": "EPSON TM-T88V Receipt5",
"state": "online"
},
{
"id": 75242714,
"name": "HP LaserJet Pro MFP M127fn",
"description": "HP LaserJet Pro MFP M127-M128 PCLmS",
"state": "online"
}
]
Crear Trabajo de Impresión:
POST https://api.printnode.com/printjobs
Authorization: Basic {credentials}
Content-Type: application/json
{
"printerId": 75290979,
"title": "Pedido #15629",
"contentType": "pdf_base64",
"content": "JVBERi0xLjQK...",
"source": "OMS Backend",
"qty": 1
}
| Campo | Descripción |
|---|---|
printerId |
ID de la impresora en PrintNode |
title |
Nombre del trabajo (visible en cola de impresión) |
contentType |
pdf_base64 - indica que el contenido es PDF en base64 |
content |
El PDF en base64 (output directo del API Gateway) |
source |
Identificador de la aplicación origen |
qty |
Cantidad de copias |
Respuesta Exitosa:
{
"id": 789456
}
Impresoras Disponibles en PrintNode¶
Lista de impresoras físicas registradas en PrintNode (actualizada: 2025-03-23):
Impresoras de Tickets (Térmicas)¶
| ID | Nombre | Modelo | Estado |
|---|---|---|---|
| 75290979 | EPSON TICKETS ST - AVIADORES | EPSON TM-T88V | online |
| 75242715 | EPSON TM-T20X Receipt | EPSON TM-T20X | online |
| 75285470 | EPSON TM-T20X Receipt | EPSON TM-T20X | online |
| 75290982 | EPSON TM-T88V Receipt5 | EPSON TM-T88V | online |
Impresoras de Papel (Láser/Inkjet)¶
| ID | Nombre | Modelo | Estado |
|---|---|---|---|
| 75242714 | HP LaserJet Pro MFP M127fn | HP LaserJet Pro M127-M128 | online |
| 75242716 | Kyocera FS-1035MFP KX | Kyocera FS-1035MFP | online |
| 75242718 | HP LaserJet Pro MFP M127-M128 PCLmS | HP LaserJet Pro M127-M128 | online |
| 75285474 | HP 107 WIFI | HP Laser 107 | online |
| 75242720 | EPSON9C320A (L395 Series) | Epson L395 | online |
Nota: Para obtener la lista actualizada de impresoras, usar el endpoint
GET /api/printerso consultar directamente a PrintNode.
Payload de Impresión (Frontend → Backend)¶
Tipos de Documento Soportados¶
| documentType | Documento | Layout | Estado |
|---|---|---|---|
order |
Pedido de Venta | RCRI0026 |
✅ Disponible |
invoice |
Factura de Ventas | RCRI0029 |
✅ Disponible |
payment |
Recibo de Cobro | RCRI0030 |
✅ Disponible |
delivery |
Nota de Entrega | RCRI0031 |
✅ Disponible |
creditNote |
Nota de Crédito | RCRI0032 |
✅ Disponible |
serviceCall |
Orden de Servicio | - | ⏳ Pendiente crear layout |
quotation |
Cotización | - | ⏳ Pendiente crear layout |
Opción 1: Usar impresora por defecto del usuario
{
"documentType": "order",
"docEntry": 33008,
"docNum": 15629,
"printerType": "ticket"
}
Opción 2: Especificar impresora manualmente
{
"documentType": "order",
"docEntry": 33008,
"docNum": 15629,
"printerType": "ticket",
"printerId": 75290979
}
Si
printerIdestá presente, se usa esa impresora. Si no, se usa la configurada en UserDefaultGroups.
Respuesta del Backend (Backend → Frontend)¶
{
"success": true,
"printJobId": 789456,
"message": "Documento enviado a imprimir"
}
Flujo Interno del Backend¶
- Recibe request del frontend con
documentType,docEntry,docNum,printerType,printerId(opcional) - Obtiene el
layoutCodedel .env segúndocumentType(order → REPORT_LAYOUT_ORDER, invoice → REPORT_LAYOUT_INVOICE) - Si
printerIdviene en el request → usar ese ID directamente - Si NO viene
printerId: - Consulta UserDefaultGroups del usuario en SAP Service Layer
- Obtiene el
printerIdsegúnprinterType:ticket→U_PrinterTicketpaper→U_PrinterPaperlabel→U_PrinterLabel
- Si el campo está vacío → retorna error indicando que debe seleccionar impresora
- Obtiene sesión válida del API Gateway (login o cache)
- Llama a
ExportPDFDatacon ellayoutCodey parámetros del documento - Recibe PDF en base64 del API Gateway
- Envía el PDF (base64) a PrintNode con
printerIdyqty: 1 - Recibe
printJobIdde PrintNode - Retorna confirmación al frontend
11. Dependencias¶
| ID Historia | Título | Tipo de dependencia |
|---|---|---|
| - | Configuración de PrintNode (API Key) | Bloqueante |
| - | Registro de impresoras en PrintNode | Bloqueante |
| - | Creación de UDFs en SAP (U_PrinterTicket, U_PrinterPaper, U_PrinterLabel) | Bloqueante |
| - | Configuración de UserDefaultGroups por usuario con IDs de impresoras | Bloqueante |
12. Definición de Hecho (DoD)¶
- [ ] Código desarrollado y revisado (PR aprobado)
- [ ] Pruebas unitarias escritas y aprobadas
- [ ] Pruebas de integración pasadas
- [ ] Criterios de aceptación validados
- [ ] Documentación actualizada
- [ ] Desplegado en ambiente de QA
13. Estimación¶
| Métrica | Valor |
|---|---|
| Story Points | - |
| Esfuerzo estimado (horas) | - |
| Sprint asignado | - |
14. Historial de Cambios¶
| Fecha | Autor | Cambio realizado |
|---|---|---|
| 2025-03-23 | - | Versión inicial |
| 2025-03-23 | - | Actualización: impresoras desde UserDefaultGroups de SAP |
| 2025-03-23 | - | UDFs creados en SAP: U_PrinterTicket, U_PrinterPaper, U_PrinterLabel |
| 2025-03-23 | - | Agregada lista de impresoras disponibles en PrintNode |
| 2025-03-23 | - | Cambio: si no tiene impresora asignada, puede seleccionar una |
| 2026-03-24 | - | Agregados layouts: payment (RCRI0030), delivery (RCRI0031), creditNote (RCRI0032) |
| 2026-03-24 | - | Documentados layouts pendientes: serviceCall, quotation, inventoryTransfer, label |