feat: Endpoints para imprimir templates y operaciones con variables
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 36s
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 36s
- POST /api/print/template: Imprime un template guardado por ID con variables - POST /api/print/raw: Imprime operaciones arbitrarias con soporte de variables inline - Agregada función resolveVariables() en server/utils/templates.ts
This commit is contained in:
87
server/api/print/raw.post.ts
Normal file
87
server/api/print/raw.post.ts
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
// Endpoint para imprimir operaciones arbitrarias con variables inline
|
||||||
|
import { buildFromOperations } from '../../utils/eposBuilder'
|
||||||
|
import { buildSoapEnvelope, sendToPrinter, parsePrinterResponse } from '../../utils/printer'
|
||||||
|
import { getSelectedPrinter, getPrinterById } from '../../utils/printers'
|
||||||
|
import { resolveVariables, Operation } from '../../utils/templates'
|
||||||
|
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
try {
|
||||||
|
const body = await readBody(event)
|
||||||
|
|
||||||
|
const {
|
||||||
|
operations,
|
||||||
|
variables = {},
|
||||||
|
dryRun = false,
|
||||||
|
printerId
|
||||||
|
} = body as {
|
||||||
|
operations: Operation[]
|
||||||
|
variables?: Record<string, string>
|
||||||
|
dryRun?: boolean
|
||||||
|
printerId?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validar operations
|
||||||
|
if (!operations || !Array.isArray(operations) || operations.length === 0) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
error: 'operations es requerido y debe ser un array no vacío'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolver variables en las operaciones
|
||||||
|
const resolvedOperations = resolveVariables(operations, variables)
|
||||||
|
|
||||||
|
// Construir el XML
|
||||||
|
const inner = buildFromOperations(resolvedOperations)
|
||||||
|
const soap = buildSoapEnvelope(inner)
|
||||||
|
|
||||||
|
// Si es dryRun, devolver sin enviar a la impresora
|
||||||
|
if (dryRun) {
|
||||||
|
return {
|
||||||
|
ok: true,
|
||||||
|
dryRun: true,
|
||||||
|
soap,
|
||||||
|
resolvedOperations
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtener la impresora
|
||||||
|
let printer = printerId
|
||||||
|
? await getPrinterById(printerId)
|
||||||
|
: await getSelectedPrinter()
|
||||||
|
|
||||||
|
if (!printer) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
error: 'No hay impresora configurada. Por favor, agrega una impresora primero.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enviar a la impresora
|
||||||
|
const result = await sendToPrinter(
|
||||||
|
soap,
|
||||||
|
printer.host,
|
||||||
|
printer.deviceId,
|
||||||
|
printer.timeout
|
||||||
|
)
|
||||||
|
|
||||||
|
// Parsear la respuesta
|
||||||
|
const { success, code } = parsePrinterResponse(result.data)
|
||||||
|
|
||||||
|
return {
|
||||||
|
ok: success,
|
||||||
|
httpStatus: result.status,
|
||||||
|
code,
|
||||||
|
raw: result.data,
|
||||||
|
printerUsed: {
|
||||||
|
id: printer.id,
|
||||||
|
name: printer.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
error: err.message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
100
server/api/print/template.post.ts
Normal file
100
server/api/print/template.post.ts
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
// Endpoint para imprimir un template guardado con variables resueltas
|
||||||
|
import { buildFromOperations } from '../../utils/eposBuilder'
|
||||||
|
import { buildSoapEnvelope, sendToPrinter, parsePrinterResponse } from '../../utils/printer'
|
||||||
|
import { getSelectedPrinter, getPrinterById } from '../../utils/printers'
|
||||||
|
import { getTemplateById, resolveVariables } from '../../utils/templates'
|
||||||
|
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
try {
|
||||||
|
const body = await readBody(event)
|
||||||
|
|
||||||
|
const {
|
||||||
|
templateId,
|
||||||
|
variables = {},
|
||||||
|
dryRun = false,
|
||||||
|
printerId
|
||||||
|
} = body as {
|
||||||
|
templateId: string
|
||||||
|
variables?: Record<string, string>
|
||||||
|
dryRun?: boolean
|
||||||
|
printerId?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validar templateId
|
||||||
|
if (!templateId) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
error: 'templateId es requerido'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtener el template
|
||||||
|
const template = await getTemplateById(templateId)
|
||||||
|
if (!template) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
error: `Template no encontrado: ${templateId}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolver variables en las operaciones
|
||||||
|
const resolvedOperations = resolveVariables(template.operations, variables)
|
||||||
|
|
||||||
|
// Construir el XML
|
||||||
|
const inner = buildFromOperations(resolvedOperations)
|
||||||
|
const soap = buildSoapEnvelope(inner)
|
||||||
|
|
||||||
|
// Si es dryRun, devolver sin enviar a la impresora
|
||||||
|
if (dryRun) {
|
||||||
|
return {
|
||||||
|
ok: true,
|
||||||
|
dryRun: true,
|
||||||
|
templateId: template.id,
|
||||||
|
templateName: template.name,
|
||||||
|
soap,
|
||||||
|
resolvedOperations
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtener la impresora
|
||||||
|
let printer = printerId
|
||||||
|
? await getPrinterById(printerId)
|
||||||
|
: await getSelectedPrinter()
|
||||||
|
|
||||||
|
if (!printer) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
error: 'No hay impresora configurada. Por favor, agrega una impresora primero.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enviar a la impresora
|
||||||
|
const result = await sendToPrinter(
|
||||||
|
soap,
|
||||||
|
printer.host,
|
||||||
|
printer.deviceId,
|
||||||
|
printer.timeout
|
||||||
|
)
|
||||||
|
|
||||||
|
// Parsear la respuesta
|
||||||
|
const { success, code } = parsePrinterResponse(result.data)
|
||||||
|
|
||||||
|
return {
|
||||||
|
ok: success,
|
||||||
|
templateId: template.id,
|
||||||
|
templateName: template.name,
|
||||||
|
httpStatus: result.status,
|
||||||
|
code,
|
||||||
|
raw: result.data,
|
||||||
|
printerUsed: {
|
||||||
|
id: printer.id,
|
||||||
|
name: printer.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
error: err.message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -55,6 +55,21 @@ export function extractVariables(operations: Operation[]): TemplateVariable[] {
|
|||||||
return Array.from(variablesMap.values())
|
return Array.from(variablesMap.values())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resolver variables en operaciones reemplazando {{nombre}} con valores
|
||||||
|
export function resolveVariables(
|
||||||
|
operations: Operation[],
|
||||||
|
values: Record<string, string> = {}
|
||||||
|
): Operation[] {
|
||||||
|
return JSON.parse(JSON.stringify(operations)).map((op: Operation) => {
|
||||||
|
for (const [key, val] of Object.entries(op)) {
|
||||||
|
if (typeof val === 'string') {
|
||||||
|
op[key] = val.replace(VARIABLE_REGEX, (_, name) => values[name] ?? '')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return op
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export interface TemplatesStore {
|
export interface TemplatesStore {
|
||||||
templates: PrintTemplate[]
|
templates: PrintTemplate[]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user