Skip to content

Latest commit

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

FiscalClass — Biblioteca Clarion para Controladores Fiscales

Biblioteca de clases Clarion para integración con controladores fiscales electrónicos argentinos. Gestiona la comunicación HTTP/JSON con la impresora, el ciclo de vida completo de comprobantes (facturas, notas de crédito, cierres), auditoría y logging.

Autor: Gustavo Saracca
Plataforma: Clarion (CLW/INC)
Contacto:gsaracca@gmail.comPaís: Argentina — Controladores fiscales homologados AFIP
Licencia:MIT


Índice

  1. Requisitos y dependencias
  2. Estructura de archivos
  3. Arquitectura general
  4. Configuración inicial (FiscalConfig)
  5. Inicialización de conexión (FiscalClass)
  6. Capa de transporte HTTP (FiscalHTTP)
  7. Comandos disponibles
  8. Orquestador de documentos (FiscalOrchestra)
  9. Tipos y enumeraciones (FiscalTypes)
  10. Manejo de errores (FiscalErrors)
  11. Logging (FiscalLog)
  12. Protocolo JSON
  13. Flujo de trabajo completo
  14. Referencia de bases de datos

1. Requisitos y dependencias

Bibliotecas externas requeridas

ArchivoPropósito
LibCurl.inc / LibCurl.libComunicación HTTP (POST al controlador fiscal)
cJson.inc / cJson.libSerialización/deserialización JSON
..\access\access.libUtilidades de base de datos y presentación de mensajes
..\group\group.libGestión de variables globales (ZVar_GetAndSet)

Wrapper Clarion para la biblioteca libcurl, que permite realizar peticiones HTTP/HTTPS desde código Clarion nativo. FiscalClass la utiliza a través de TCurlClass para enviar los comandos JSON al controlador fiscal mediante HTTP POST al endpoint http://<ip>/fiscal.json. Es un requisito indispensable: sin esta biblioteca, todos los comandos fallan con HTTP:CURL_ERROR.

La DLL libcurl.dll debe estar disponible en el PATH del sistema o en la carpeta del ejecutable.

Wrapper Clarion para el parser cJSON, que provee serialización y deserialización de documentos JSON. FiscalClass lo utiliza para construir los payloads de cada comando (solicitudes) y para interpretar las respuestas del controlador fiscal (éxito, error, ControladorOcupado). Sin esta biblioteca no es posible comunicarse con el controlador, ya que el protocolo completo está basado en JSON.

Variables globales requeridas (via ZVar_GetAndSet)

VariableTipoDescripción
Fiscal.LogLONG1 = logging habilitado, 0 = deshabilitado

Tabla SQL requerida: pdf_config

-- Mapea cada punto de venta (PDF) a la IP del controlador fiscal
pdf_config (
id_pdf -- Identificador del punto de venta
ip -- Dirección IP del controlador fiscal (ej: "192.168.1.50")
)

Tabla SQL requerida: pdf_fiscales

-- Mapea el número de serie fiscal a configuración del punto de venta
pdf_fiscales (
serie -- Número de serie del controlador (ej: "A12345678")
prefijo -- Prefijo del comprobante (ej: "0001")
marca -- 1=Epson, 2=Hasar, 9=Virtual
modelo -- Ver enumeración Fiscal_Type en FiscalTypes.inc
if_nc -- Flag notas de crédito
)

2. Estructura de archivos

FiscalClass/
│
├── FiscalTypes.inc ← Enumeraciones y constantes globales
│
├── FiscalConfig.clw / .inc ← Singleton de configuración global
├── FiscalLog.clw / .inc ← Subsistema de logging
├── FiscalErrors.clw / .inc ← Registro de códigos de error
├── FiscalTools.clw / .inc ← Utilidades (zonas, flags de texto)
│
├── FiscalHTTP.clw / .inc ← Capa HTTP con LibCurl
├── FiscalCommand.clw / .inc ← Clase base de comandos + lógica de reintentos
│
├── FiscalClass.clw / .inc ← Coordinador principal (conexión, inicialización)
│
│ ── Comandos específicos ──
├── FiscalInicializacion.clw / .inc ← Consulta datos del controlador
├── FiscalConsultarEstado.clw / .inc ← Estado actual del controlador
├── FiscalCancelar.clw / .inc ← Cancelar operación en curso
├── FiscalCierreX.clw / .inc ← Informe X (subtotal sin borrar)
├── FiscalCierreZ.clw / .inc ← Cierre Z (cierre diario definitivo)
├── FiscalAuditDate.clw / .inc ← Auditoría por rango de fechas
├── FiscalAuditNumber.clw / .inc ← Auditoría por rango de número Z
├── FiscalCopiarComprobante.clw / .inc← Reimpresión de comprobante
│
├── FiscalOrchestra.clw / .inc ← Orquestador de alto nivel (workflow completo)
├── FiscalMail.clw ← Envío de documentos por correo
│
└── PulseBarClass.clw / .inc ← Control visual de progreso (barra animada)

3. Arquitectura general

La biblioteca está organizada en capas bien definidas:

┌─────────────────────────────────────────────────────┐
│ FiscalOrchestra │ ← Capa de aplicación
│ (workflow, UI, cola de comandos) │
└─────────────────┬───────────────────────────────────┘
│ usa
┌─────────────────▼───────────────────────────────────┐
│ FiscalInicializacion FiscalCierreZ FiscalCierreX │ ← Comandos concretos
│ FiscalConsultarEstado FiscalCancelar FiscalAudit… │
└─────────────────┬───────────────────────────────────┘
│ heredan
┌─────────────────▼───────────────────────────────────┐
│ FiscalCommand / FiscalCommandClass │ ← Base: JSON + reintentos
└─────────────────┬───────────────────────────────────┘
│ hereda
┌─────────────────▼───────────────────────────────────┐
│ FiscalHTTP │ ← HTTP POST via LibCurl
└─────────────────────────────────────────────────────┘
Transversal a todas las capas:
FiscalConfig (singleton de configuración)
FiscalLog (logging a archivo)
FiscalErrors (catálogo de errores)

Jerarquía de herencia de clases

FiscalHTTP
└─ FiscalCommandClass
└─ FiscalCommand (wrapper con reintentos automáticos)
├─ FiscalInicializacion
├─ FiscalConsultarEstado
├─ FiscalCancelar
├─ FiscalCierreX
├─ FiscalCierreZ
├─ FiscalAuditDate
├─ FiscalAuditNumber
└─ FiscalCopiarComprobante

4. Configuración inicial (FiscalConfig)

FiscalConfig es un objeto global singleton (instancia única compartida). No debe ser instanciado manualmente; se accede a través de su instancia global.

Propiedades configurables

MétodoDescripción
SetIP(string)IP del controlador fiscal
SetSerial(string)Número de serie del controlador
SetMarca(long)Marca: 1=Epson, 2=Hasar, 9=Virtual
SetModelo(long)Modelo (ver Fiscal_Type en FiscalTypes.inc)
SetPrefijo(string)Prefijo del punto de venta (ej: "0001")
SetNC(long)Flag notas de crédito
SetIIBB(string)Número de inscripción IIBB
SetCondIVA(long)Condición frente al IVA
SetLogEnable(long)Habilitar/deshabilitar logging
SetLogFilename(string)Ruta base del archivo de log
SetMsgBox(long)Controla presentación de mensajes

Mapeo de marca a string

1 → "Epson"
2 → "Hasar"
9 → "Virtual"

Mapeo de modelo a string

Fiscal_TM2000AF → "TM2000AF"
Fiscal_TM2000AFplus→ "TM2000AF+"
Fiscal_TMU220AF → "TMU220AF"
Fiscal_ND_3 → "N/A-3"
Fiscal_ND_5 → "N/A-5"
Fiscal_LX300 → "LX-300"
Fiscal_Hasar_441 → "441"
Fiscal_Hasar_1000 → "1000"

5. Inicialización de conexión (FiscalClass)

FiscalClass coordina la inicialización completa leyendo la configuración desde la base de datos.

Métodos principales

MétodoDescripción
SetPDF(long)Define el ID del punto de venta
SetConnectionString(string)Cadena de conexión SQL
Open()Ejecuta el flujo completo de inicialización
LoadIP()Lee la IP desde pdf_config
LoadFiscal()Consulta el controlador y carga serial/prefijo
LoadParams()Lee marca y modelo desde pdf_fiscales

Flujo de Open()

Open()
├─ LoadIP() → Lee ip de pdf_config WHERE id_pdf = @pdf
├─ LoadFiscal() → Ejecuta FiscalInicializacion, guarda serial/prefijo
└─ LoadParams() → Lee marca/modelo de pdf_fiscales WHERE serie = @serial

Atributos disponibles tras Open()

oFiscal.GetPDF()! ID del punto de venta
oFiscal.GetPrefijo()! Prefijo cargado desde controlador
oFiscal.GetConfigPrefijo()! Prefijo cargado desde base de datos

6. Capa de transporte HTTP (FiscalHTTP)

FiscalHTTP encapsula la comunicación HTTP POST usando TCurlClass (LibCurl).

Endpoint

POST http://<ip>/fiscal.json
Content-Type: application/json

Atributos de resultado

AtributoDescripción
HTTPCodeCódigo de respuesta HTTP
HTTPMessageCuerpo de la respuesta (JSON)
HTTPErrorCódigo de error interno

Códigos de error HTTP internos

HTTP:CURL_OK =0! ExitosoHTTP:CURL_ERROR =1! Error de LibCurlHTTP:NET_ERROR =2! Respuesta HTTP 3xx-5xx

7. Comandos disponibles

Todos los comandos heredan de FiscalCommand e implementan el método Run().

7.1 FiscalInicializacion

Consulta los datos de identificación del controlador fiscal.

Respuesta relevante:

  • CUIT del emisor
  • Razón social
  • Número de serie
  • Prefijo del punto de venta
oInit.Init(oConfig)IF oInit.Run()= FISCAL_OK
serial = oInit.GetSerial()
prefijo = oInit.GetPrefijo()
cuit = oInit.GetCUIT()END

7.2 FiscalConsultarEstado

Obtiene el estado actual del controlador y el último comprobante emitido.

oEstado.Init(oConfig)IF oEstado.Run()= FISCAL_OK
estado = oEstado.GetEstado()
ultimo = oEstado.GetUltimoComprobante()END

7.3 FiscalCancelar

Cancela la operación en curso en el controlador.

oCancel.Init(oConfig)
oCancel.Run()

7.4 FiscalCierreX — Informe X

Emite un informe de subtotales sin borrar la memoria fiscal. Equivale a un "corte X" en terminología fiscal.

oCierreX.Init(oConfig)IF oCierreX.Run()= FISCAL_OK
! Informe impreso en el controladorEND

7.5 FiscalCierreZ — Cierre diario

Emite el cierre diario definitivo. Borra los acumuladores y avanza el contador Z.

oCierreZ.Init(oConfig)IF oCierreZ.Run()= FISCAL_OK
nroZ = oCierreZ.GetNroZ()
totalZ = oCierreZ.GetTotal()END

Importante: Esta operación es irreversible. El controlador fiscal homologado no permite anular un cierre Z.

7.6 FiscalAuditDate — Auditoría por fecha

Imprime el informe de auditoría para un rango de fechas.

oAudit.Init(oConfig)
oAudit.SetFechaDesde('20260101')
oAudit.SetFechaHasta('20260131')
oAudit.Run()

7.7 FiscalAuditNumber — Auditoría por número Z

Imprime el informe de auditoría para un rango de números de cierre Z.

oAuditN.Init(oConfig)
oAuditN.SetZDesde(100)
oAuditN.SetZHasta(150)
oAuditN.Run()

7.8 FiscalCopiarComprobante

Reimprime una copia de un comprobante emitido.

oCopia.Init(oConfig)
oCopia.SetNumeroComprobante(12345)
oCopia.Run()

8. Orquestador de documentos (FiscalOrchestra)

FiscalOrchestra es el componente de más alto nivel. Gestiona el ciclo de vida completo de un comprobante fiscal, acumulando comandos en una cola y ejecutándolos con una UI de progreso.

Inicialización

oOrch.Init('Emisión Factura B')! Título visible en la ventana de progreso
oOrch.SetConfig(oConfig)

Métodos de construcción del documento

Cliente (datos del receptor)

oOrch.Cliente(
cuit,! CUIT del cliente (string, sin guiones)
razonSocial,! Razón social o nombre
domicilio,! Domicilio completo
condIVA ! Ver FiscalCondIVA en FiscalTypes.inc)

Título (cabecera del comprobante)

oOrch.Titulo(
tipoDoc,! Ver FiscalDocType en FiscalTypes.inc (ej: Doc_FacturaB)
copias,! Cantidad de copias a imprimir
referencia ! Número de comprobante de referencia (para NC/ND))

Ítem (líneas del cuerpo)

oOrch.Item(
descripcion,! Texto de la línea
cantidad,! Cantidad (DECIMAL)
precioUnitario,! Precio unitario (DECIMAL)
ivaCondicion,! Ver FiscalIVACond (Gravado, Exento, NoGravado)
ivaAlicuota,! Alícuota de IVA (ej: 21.00)
codigoProducto ! Código interno del producto)

Pago

oOrch.Pago(
medioPago,! Ver FiscalPayment en FiscalTypes.inc
importe,! Importe del pago (DECIMAL)
descripcion ! Descripción opcional)

Percepción

oOrch.Percepcion(
tipoImpuesto,! Ver FiscalTaxType
alicuota,! Alícuota
importe ! Importe percibido)

Bonificación / Descuento

oOrch.Bonif(
descripcion,
importe,! Positivo = descuento, negativo = recargo
ivaCondicion
)

Ajuste

oOrch.Ajuste(descripcion, importe)

Cierre del comprobante

oOrch.Cierre()

Sección no fiscal (textos sin efecto fiscal)

oOrch.TituloNF(texto)! Título de sección no fiscal
oOrch.TextoNF(texto)! Línea de texto libre
oOrch.CierreNF()! Cierre de sección no fiscal

Zonas de texto (header/footer del comprobante)

oOrch.ZonaHead(texto, atributos)! Encabezado del ticket
oOrch.ZonaFoot(texto, atributos)! Pie del ticket
oOrch.ZonaDomicilioEmisor(texto)! Domicilio del emisor
oOrch.ZonaFantasia(texto)! Nombre de fantasía

Los atributos de texto se combinan con OR de bit usando las constantes de FiscalTextAttr:

! Ejemplo: texto centrado y negritaattr = FiscalAttr_Centered |: FiscalAttr_Bold
oOrch.ZonaHead('MI EMPRESA S.A.', attr)

Ejecución

oOrch.Run()! Abre ventana de progreso y ejecuta toda la cola de comandos

Run() muestra una ventana modal con:

  • Lista de comandos pendientes / ejecutados
  • Barra animada de progreso (PulseBarClass) durante reintentos
  • Botón cancelar (pregunta confirmación antes de abortar)

Ventana de progreso del orquestador

Cancelación

oOrch.Cancelar()! Cancela la operación en curso en el controlador
oOrch.AskAbort()! Pide confirmación al usuario antes de cancelar

9. Tipos y enumeraciones (FiscalTypes)

Todas las constantes están definidas en FiscalTypes.inc.

Tipos de controlador (Fiscal_Type)

Fiscal_TM2000AF ! Epson TM-2000AF
Fiscal_TM2000AFplus! Epson TM-2000AF+Fiscal_TMU220AF ! Epson TM-U220AFFiscal_ND_3 ! Genérico N/A-3Fiscal_ND_5 ! Genérico N/A-5Fiscal_LX300 ! Epson LX-300Fiscal_Hasar_441 ! Hasar 441Fiscal_Hasar_1000 ! Hasar 1000

Tipos de documento (FiscalDocType)

Doc_FacturaA  Doc_FacturaB Doc_FacturaC
Doc_NotaDeCreditoA  Doc_NotaDeCreditoB Doc_NotaDeCreditoC
Doc_NotaDeDebitoA  Doc_NotaDeDebitoB Doc_NotaDeDebitoC
Doc_ReciboA  Doc_ReciboB Doc_ReciboC
Doc_TiqueFacturaA  Doc_TiqueFacturaB Doc_TiqueFacturaC
Doc_TiqueNotaCreditoDoc_InformeDiarioDeCierre ! Cierre ZDoc_DetalleDeVentas ! Informe XDoc_Remito  Doc_Presupuesto Doc_MensajeCF
Doc_ComprobanteDonacion! ... y más de 40 tipos en total

Condición IVA del ítem (FiscalIVACond)

IVA_GravadoIVA_ExentoIVA_NoGravado

Responsabilidad IVA del emisor/receptor (FiscalCondIVA)

IVA_ResponsableInscriptoIVA_ExentoIVA_NoResponsableIVA_MonotributoIVA_ResponsableMonotributoIVA_GranContribuyenteIVA_Consumidor_Final

Medios de pago (FiscalPayment)

Pay_Efectivo  Pay_Cheque
Pay_TarjetaCredito  Pay_TarjetaDebito
Pay_TransferenciaBancaria Pay_CuentaCorriente
Pay_Vales  Pay_Otro
! ... más de 30 tipos

Tipos de impuesto adicional (FiscalTaxType)

Tax_Nacional  Tax_Provincial Tax_Municipal
Tax_Interno  Tax_IIBB Tax_PercepcionIVA

Atributos de texto (FiscalTextAttr) — flags de bit

FiscalAttr_Deleted =01H! TachadoFiscalAttr_Wide =02H! Ancho dobleFiscalAttr_Centered =04H! CentradoFiscalAttr_Bold =08H! Negrita

Estaciones de impresión (FiscalStation)

Station_TicketStation_SlipStation_Default

Zonas del comprobante (FiscalZone)

Zone_Fantasia ! Nombre de fantasíaZone_Domicilio ! Domicilio del emisorZone_Header1 ! Encabezado línea 1Zone_Header2 ! Encabezado línea 2Zone_Footer1 ! Pie línea 1Zone_Footer2 ! Pie línea 2

10. Manejo de errores (FiscalErrors)

Flags de estado (combinables con OR de bit)

FISCAL_OK =000H! Sin erroresFISCAL_ERROR =001H! Error genéricoFISCAL_PRINTER_ERROR =002H! Error físico de impresoraFISCAL_SYNTAX_ERROR =004H! Error de sintaxis de comandoFISCAL_NET_ERROR =008H! Error de red/HTTPFISCAL_BUSY =010H! Controlador ocupadoFISCAL_RESPONSE_ERROR =020H! Respuesta inesperadaFISCAL_UNKNOWN =040H! Estado desconocidoFISCAL_UNKNOWN_COMMAND =080H! Comando no reconocidoFISCAL_AUX =100H! Mensaje auxiliarFISCAL_INTERNAL =200H! Error interno del controlador

Categorías de mensajes del controlador

Los mensajes del controlador están catalogados en rangos numéricos:

RangoCategoría
101–116FISCAL_PRINTER_ERROR — Error físico de impresora
201–216FISCAL_ERROR — Error fiscal/lógico
301–307FISCAL_AUX — Mensajes auxiliares informativos
400–417FISCAL_INTERNAL — Errores internos del controlador

Consulta de descripción de error

desc = oErrors.GetErrorDesc(codigo)! Retorna descripción en español

FiscalErrors contiene un catálogo de más de 200 códigos de error clasificados en categorías: Sistema, E/S, Socket, XML, JSON, Criptografía, Imagen, POS, Auditoría, Memoria Fiscal, Aritmética, Base de Datos, Protocolo e Interfaz.


11. Logging (FiscalLog)

El sistema de logging registra todos los comandos enviados y respuestas recibidas.

Configuración

! Habilitar via variable de entorno (ZVar_GetAndSet)
ZVar_GetAndSet('Fiscal.Log',1)! 1 = activo, 0 = inactivo! O directamente via FiscalConfig:
oConfig.SetLogEnable(1)
oConfig.SetLogFilename('C:\Logs\fiscal')

Nombre del archivo de log

{ruta_base}_{serie}_{YYYY}_{MM}.log
Ejemplo: C:\Logs\fiscal_A12345678_2026_04.log

Formato de entrada

[2026-04-24 14:32:10] → {"AbrirComprobante":{...}}
[2026-04-24 14:32:11] ← {"AbrirComprobante":{"Secuencia":"12345",...}}

Uso programático (raramente necesario directamente)

oLog.Init(oConfig)
oLog.Write('Mensaje de texto plano')
oLog.Write(cstring_var)

Los comandos de FiscalCommand llaman a FiscalLog automáticamente en cada envío/respuesta.


12. Protocolo JSON

Formato de solicitud

{
"NombreComando": {
"Parametro1": "valor1",
"Parametro2": "valor2"
}
}

Formato de respuesta — Éxito

{
"NombreComando": {
"Secuencia": "12345",
"Estado": {
"Impresora": ["estado1", "estado2"],
"Fiscal": ["estadoFiscal1"]
},
"CamposEspecificos": "..."
}
}

Formato de respuesta — Controlador ocupado

{
"ControladorOcupado": {
"Secuencia": "12345",
"Estado": { ... }
}
}

Cuando el controlador responde ControladorOcupado, FiscalCommand entra en bucle de reintento automático. La frecuencia y cantidad de reintentos son configurables. Durante la espera, se invoca el callback MyNotifyClass que activa la animación de PulseBarClass.

Formato de respuesta — Error

{
"Error": {
"Identificador": "CODIGO_ERROR",
"Descripcion": "Descripción del error",
"Contexto": "Información adicional"
}
}

13. Flujo de trabajo completo

Ejemplo mínimo: Factura B

! 1. Crear y configurar el coordinador de conexión
oFiscal.SetPDF(idPuntDeVenta)
oFiscal.SetConnectionString(connStr)IF NOT oFiscal.Open()Message('Error al conectar con el controlador fiscal')RETURNEND! 2. Crear el orquestador
oOrch.Init('Emisión Factura B')! 3. Datos del receptor
oOrch.Cliente('20304050607','Juan Perez','Av. Corrientes 1234', IVA_Consumidor_Final)! 4. Tipo de comprobante
oOrch.Titulo(Doc_FacturaB,1,'')! 5. Ítems
oOrch.Item('Producto A',2,1500.00, IVA_Gravado,21.00,'001')
oOrch.Item('Producto B',1,800.50, IVA_Gravado,10.50,'002')! 6. Pago
oOrch.Pago(Pay_Efectivo,3800.50,'')! 7. Cerrar el comprobante
oOrch.Cierre()! 8. Ejecutar (muestra ventana de progreso)
oOrch.Run()

Ejemplo: Cierre Z diario

! Solo ejecutar si se confirmó con el operadorIFMessage('¿Confirma el Cierre Z?','Cierre Diario',BUTTON:YesNo)=BUTTON:Yes
oCierreZ.Init(oConfig)IF oCierreZ.Run()= FISCAL_OK
Message('Cierre Z N° '& oCierreZ.GetNroZ()&' realizado correctamente.')ELSEMessage('Error en Cierre Z: '& oCierreZ.GetLastError())ENDEND

Ejemplo: Auditoría por fecha

 oAudit.Init(oConfig)
oAudit.SetFechaDesde('20260101')
oAudit.SetFechaHasta('20260131')IF oAudit.Run()<> FISCAL_OK
Message('Error de auditoría: '& oAudit.GetLastError())END

14. Referencia de bases de datos

Tabla pdf_config

CampoTipoDescripción
id_pdfLONGIdentificador del punto de venta
ipSTRINGIP del controlador fiscal (ej: "192.168.1.50")

Tabla pdf_fiscales

CampoTipoDescripción
serieSTRINGNúmero de serie del controlador
prefijoSTRINGPrefijo del punto de venta (ej: "0001")
marcaLONG1=Epson, 2=Hasar, 9=Virtual
modeloLONGConstante Fiscal_Type (ver sección 9)
if_ncLONGFlag de notas de crédito

Consultas ejecutadas por FiscalClass

-- LoadIP()SELECT ip FROM pdf_config WHERE id_pdf = :pdf
-- LoadParams() (tras obtener serial del controlador)SELECT prefijo, marca, modelo, if_nc
FROM pdf_fiscales
WHERE serie = :serial

Versión

La constante FISCAL_VERSION (definida en FiscalTypes.inc) identifica la versión de la biblioteca.

Formato:YY.MM.DDX

ParteDescripciónEjemplo
YYAño (2 dígitos)26
MMMes (2 dígitos)04
DDDía (2 dígitos)25
XRevisión del día (letra: A, B, C…)A

Historial

VersiónCambios
26.04.25APrimera versión pública

Notas para el desarrollador

  • Nunca instanciar FiscalConfig directamente: es un singleton. Acceder siempre a través de su instancia global.
  • El Cierre Z es irreversible: validar siempre con el operador antes de ejecutarlo.
  • LibCurl debe estar en el PATH o en la carpeta del ejecutable: sin él, todos los comandos fallan con HTTP:CURL_ERROR.
  • El logging crea un archivo por mes: monitorear espacio en disco en instalaciones con alto volumen de comprobantes.
  • FiscalOrchestra.Run() es bloqueante: abre una ventana modal. Si se necesita integración en un proceso batch sin UI, ejecutar los comandos directamente vía sus clases concretas.
  • Reintentos por ControladorOcupado: el controlador puede estar procesando un trabajo anterior. FiscalCommand reintenta automáticamente; el desarrollador puede configurar el número de intentos y el delay entre ellos.

About

Hasar Fiscal Printer Driver

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - gsaracca/FiscalClass: Hasar Fiscal Printer Driver · GitHub
Skip to content

Latest commit

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

FiscalClass — Biblioteca Clarion para Controladores Fiscales

Biblioteca de clases Clarion para integración con controladores fiscales electrónicos argentinos. Gestiona la comunicación HTTP/JSON con la impresora, el ciclo de vida completo de comprobantes (facturas, notas de crédito, cierres), auditoría y logging.

Autor: Gustavo Saracca
Plataforma: Clarion (CLW/INC)
Contacto:gsaracca@gmail.comPaís: Argentina — Controladores fiscales homologados AFIP
Licencia:MIT


Índice

  1. Requisitos y dependencias
  2. Estructura de archivos
  3. Arquitectura general
  4. Configuración inicial (FiscalConfig)
  5. Inicialización de conexión (FiscalClass)
  6. Capa de transporte HTTP (FiscalHTTP)
  7. Comandos disponibles
  8. Orquestador de documentos (FiscalOrchestra)
  9. Tipos y enumeraciones (FiscalTypes)
  10. Manejo de errores (FiscalErrors)
  11. Logging (FiscalLog)
  12. Protocolo JSON
  13. Flujo de trabajo completo
  14. Referencia de bases de datos

1. Requisitos y dependencias

Bibliotecas externas requeridas

ArchivoPropósito
LibCurl.inc / LibCurl.libComunicación HTTP (POST al controlador fiscal)
cJson.inc / cJson.libSerialización/deserialización JSON
..\access\access.libUtilidades de base de datos y presentación de mensajes
..\group\group.libGestión de variables globales (ZVar_GetAndSet)

Wrapper Clarion para la biblioteca libcurl, que permite realizar peticiones HTTP/HTTPS desde código Clarion nativo. FiscalClass la utiliza a través de TCurlClass para enviar los comandos JSON al controlador fiscal mediante HTTP POST al endpoint http://<ip>/fiscal.json. Es un requisito indispensable: sin esta biblioteca, todos los comandos fallan con HTTP:CURL_ERROR.

La DLL libcurl.dll debe estar disponible en el PATH del sistema o en la carpeta del ejecutable.

Wrapper Clarion para el parser cJSON, que provee serialización y deserialización de documentos JSON. FiscalClass lo utiliza para construir los payloads de cada comando (solicitudes) y para interpretar las respuestas del controlador fiscal (éxito, error, ControladorOcupado). Sin esta biblioteca no es posible comunicarse con el controlador, ya que el protocolo completo está basado en JSON.

Variables globales requeridas (via ZVar_GetAndSet)

VariableTipoDescripción
Fiscal.LogLONG1 = logging habilitado, 0 = deshabilitado

Tabla SQL requerida: pdf_config

-- Mapea cada punto de venta (PDF) a la IP del controlador fiscal
pdf_config (
id_pdf -- Identificador del punto de venta
ip -- Dirección IP del controlador fiscal (ej: "192.168.1.50")
)

Tabla SQL requerida: pdf_fiscales

-- Mapea el número de serie fiscal a configuración del punto de venta
pdf_fiscales (
serie -- Número de serie del controlador (ej: "A12345678")
prefijo -- Prefijo del comprobante (ej: "0001")
marca -- 1=Epson, 2=Hasar, 9=Virtual
modelo -- Ver enumeración Fiscal_Type en FiscalTypes.inc
if_nc -- Flag notas de crédito
)

2. Estructura de archivos

FiscalClass/
│
├── FiscalTypes.inc ← Enumeraciones y constantes globales
│
├── FiscalConfig.clw / .inc ← Singleton de configuración global
├── FiscalLog.clw / .inc ← Subsistema de logging
├── FiscalErrors.clw / .inc ← Registro de códigos de error
├── FiscalTools.clw / .inc ← Utilidades (zonas, flags de texto)
│
├── FiscalHTTP.clw / .inc ← Capa HTTP con LibCurl
├── FiscalCommand.clw / .inc ← Clase base de comandos + lógica de reintentos
│
├── FiscalClass.clw / .inc ← Coordinador principal (conexión, inicialización)
│
│ ── Comandos específicos ──
├── FiscalInicializacion.clw / .inc ← Consulta datos del controlador
├── FiscalConsultarEstado.clw / .inc ← Estado actual del controlador
├── FiscalCancelar.clw / .inc ← Cancelar operación en curso
├── FiscalCierreX.clw / .inc ← Informe X (subtotal sin borrar)
├── FiscalCierreZ.clw / .inc ← Cierre Z (cierre diario definitivo)
├── FiscalAuditDate.clw / .inc ← Auditoría por rango de fechas
├── FiscalAuditNumber.clw / .inc ← Auditoría por rango de número Z
├── FiscalCopiarComprobante.clw / .inc← Reimpresión de comprobante
│
├── FiscalOrchestra.clw / .inc ← Orquestador de alto nivel (workflow completo)
├── FiscalMail.clw ← Envío de documentos por correo
│
└── PulseBarClass.clw / .inc ← Control visual de progreso (barra animada)

3. Arquitectura general

La biblioteca está organizada en capas bien definidas:

┌─────────────────────────────────────────────────────┐
│ FiscalOrchestra │ ← Capa de aplicación
│ (workflow, UI, cola de comandos) │
└─────────────────┬───────────────────────────────────┘
│ usa
┌─────────────────▼───────────────────────────────────┐
│ FiscalInicializacion FiscalCierreZ FiscalCierreX │ ← Comandos concretos
│ FiscalConsultarEstado FiscalCancelar FiscalAudit… │
└─────────────────┬───────────────────────────────────┘
│ heredan
┌─────────────────▼───────────────────────────────────┐
│ FiscalCommand / FiscalCommandClass │ ← Base: JSON + reintentos
└─────────────────┬───────────────────────────────────┘
│ hereda
┌─────────────────▼───────────────────────────────────┐
│ FiscalHTTP │ ← HTTP POST via LibCurl
└─────────────────────────────────────────────────────┘
Transversal a todas las capas:
FiscalConfig (singleton de configuración)
FiscalLog (logging a archivo)
FiscalErrors (catálogo de errores)

Jerarquía de herencia de clases

FiscalHTTP
└─ FiscalCommandClass
└─ FiscalCommand (wrapper con reintentos automáticos)
├─ FiscalInicializacion
├─ FiscalConsultarEstado
├─ FiscalCancelar
├─ FiscalCierreX
├─ FiscalCierreZ
├─ FiscalAuditDate
├─ FiscalAuditNumber
└─ FiscalCopiarComprobante

4. Configuración inicial (FiscalConfig)

FiscalConfig es un objeto global singleton (instancia única compartida). No debe ser instanciado manualmente; se accede a través de su instancia global.

Propiedades configurables

MétodoDescripción
SetIP(string)IP del controlador fiscal
SetSerial(string)Número de serie del controlador
SetMarca(long)Marca: 1=Epson, 2=Hasar, 9=Virtual
SetModelo(long)Modelo (ver Fiscal_Type en FiscalTypes.inc)
SetPrefijo(string)Prefijo del punto de venta (ej: "0001")
SetNC(long)Flag notas de crédito
SetIIBB(string)Número de inscripción IIBB
SetCondIVA(long)Condición frente al IVA
SetLogEnable(long)Habilitar/deshabilitar logging
SetLogFilename(string)Ruta base del archivo de log
SetMsgBox(long)Controla presentación de mensajes

Mapeo de marca a string

1 → "Epson"
2 → "Hasar"
9 → "Virtual"

Mapeo de modelo a string

Fiscal_TM2000AF → "TM2000AF"
Fiscal_TM2000AFplus→ "TM2000AF+"
Fiscal_TMU220AF → "TMU220AF"
Fiscal_ND_3 → "N/A-3"
Fiscal_ND_5 → "N/A-5"
Fiscal_LX300 → "LX-300"
Fiscal_Hasar_441 → "441"
Fiscal_Hasar_1000 → "1000"

5. Inicialización de conexión (FiscalClass)

FiscalClass coordina la inicialización completa leyendo la configuración desde la base de datos.

Métodos principales

MétodoDescripción
SetPDF(long)Define el ID del punto de venta
SetConnectionString(string)Cadena de conexión SQL
Open()Ejecuta el flujo completo de inicialización
LoadIP()Lee la IP desde pdf_config
LoadFiscal()Consulta el controlador y carga serial/prefijo
LoadParams()Lee marca y modelo desde pdf_fiscales

Flujo de Open()

Open()
├─ LoadIP() → Lee ip de pdf_config WHERE id_pdf = @pdf
├─ LoadFiscal() → Ejecuta FiscalInicializacion, guarda serial/prefijo
└─ LoadParams() → Lee marca/modelo de pdf_fiscales WHERE serie = @serial

Atributos disponibles tras Open()

oFiscal.GetPDF()! ID del punto de venta
oFiscal.GetPrefijo()! Prefijo cargado desde controlador
oFiscal.GetConfigPrefijo()! Prefijo cargado desde base de datos

6. Capa de transporte HTTP (FiscalHTTP)

FiscalHTTP encapsula la comunicación HTTP POST usando TCurlClass (LibCurl).

Endpoint

POST http://<ip>/fiscal.json
Content-Type: application/json

Atributos de resultado

AtributoDescripción
HTTPCodeCódigo de respuesta HTTP
HTTPMessageCuerpo de la respuesta (JSON)
HTTPErrorCódigo de error interno

Códigos de error HTTP internos

HTTP:CURL_OK =0! ExitosoHTTP:CURL_ERROR =1! Error de LibCurlHTTP:NET_ERROR =2! Respuesta HTTP 3xx-5xx

7. Comandos disponibles

Todos los comandos heredan de FiscalCommand e implementan el método Run().

7.1 FiscalInicializacion

Consulta los datos de identificación del controlador fiscal.

Respuesta relevante:

  • CUIT del emisor
  • Razón social
  • Número de serie
  • Prefijo del punto de venta
oInit.Init(oConfig)IF oInit.Run()= FISCAL_OK
serial = oInit.GetSerial()
prefijo = oInit.GetPrefijo()
cuit = oInit.GetCUIT()END

7.2 FiscalConsultarEstado

Obtiene el estado actual del controlador y el último comprobante emitido.

oEstado.Init(oConfig)IF oEstado.Run()= FISCAL_OK
estado = oEstado.GetEstado()
ultimo = oEstado.GetUltimoComprobante()END

7.3 FiscalCancelar

Cancela la operación en curso en el controlador.

oCancel.Init(oConfig)
oCancel.Run()

7.4 FiscalCierreX — Informe X

Emite un informe de subtotales sin borrar la memoria fiscal. Equivale a un "corte X" en terminología fiscal.

oCierreX.Init(oConfig)IF oCierreX.Run()= FISCAL_OK
! Informe impreso en el controladorEND

7.5 FiscalCierreZ — Cierre diario

Emite el cierre diario definitivo. Borra los acumuladores y avanza el contador Z.

oCierreZ.Init(oConfig)IF oCierreZ.Run()= FISCAL_OK
nroZ = oCierreZ.GetNroZ()
totalZ = oCierreZ.GetTotal()END

Importante: Esta operación es irreversible. El controlador fiscal homologado no permite anular un cierre Z.

7.6 FiscalAuditDate — Auditoría por fecha

Imprime el informe de auditoría para un rango de fechas.

oAudit.Init(oConfig)
oAudit.SetFechaDesde('20260101')
oAudit.SetFechaHasta('20260131')
oAudit.Run()

7.7 FiscalAuditNumber — Auditoría por número Z

Imprime el informe de auditoría para un rango de números de cierre Z.

oAuditN.Init(oConfig)
oAuditN.SetZDesde(100)
oAuditN.SetZHasta(150)
oAuditN.Run()

7.8 FiscalCopiarComprobante

Reimprime una copia de un comprobante emitido.

oCopia.Init(oConfig)
oCopia.SetNumeroComprobante(12345)
oCopia.Run()

8. Orquestador de documentos (FiscalOrchestra)

FiscalOrchestra es el componente de más alto nivel. Gestiona el ciclo de vida completo de un comprobante fiscal, acumulando comandos en una cola y ejecutándolos con una UI de progreso.

Inicialización

oOrch.Init('Emisión Factura B')! Título visible en la ventana de progreso
oOrch.SetConfig(oConfig)

Métodos de construcción del documento

Cliente (datos del receptor)

oOrch.Cliente(
cuit,! CUIT del cliente (string, sin guiones)
razonSocial,! Razón social o nombre
domicilio,! Domicilio completo
condIVA ! Ver FiscalCondIVA en FiscalTypes.inc)

Título (cabecera del comprobante)

oOrch.Titulo(
tipoDoc,! Ver FiscalDocType en FiscalTypes.inc (ej: Doc_FacturaB)
copias,! Cantidad de copias a imprimir
referencia ! Número de comprobante de referencia (para NC/ND))

Ítem (líneas del cuerpo)

oOrch.Item(
descripcion,! Texto de la línea
cantidad,! Cantidad (DECIMAL)
precioUnitario,! Precio unitario (DECIMAL)
ivaCondicion,! Ver FiscalIVACond (Gravado, Exento, NoGravado)
ivaAlicuota,! Alícuota de IVA (ej: 21.00)
codigoProducto ! Código interno del producto)

Pago

oOrch.Pago(
medioPago,! Ver FiscalPayment en FiscalTypes.inc
importe,! Importe del pago (DECIMAL)
descripcion ! Descripción opcional)

Percepción

oOrch.Percepcion(
tipoImpuesto,! Ver FiscalTaxType
alicuota,! Alícuota
importe ! Importe percibido)

Bonificación / Descuento

oOrch.Bonif(
descripcion,
importe,! Positivo = descuento, negativo = recargo
ivaCondicion
)

Ajuste

oOrch.Ajuste(descripcion, importe)

Cierre del comprobante

oOrch.Cierre()

Sección no fiscal (textos sin efecto fiscal)

oOrch.TituloNF(texto)! Título de sección no fiscal
oOrch.TextoNF(texto)! Línea de texto libre
oOrch.CierreNF()! Cierre de sección no fiscal

Zonas de texto (header/footer del comprobante)

oOrch.ZonaHead(texto, atributos)! Encabezado del ticket
oOrch.ZonaFoot(texto, atributos)! Pie del ticket
oOrch.ZonaDomicilioEmisor(texto)! Domicilio del emisor
oOrch.ZonaFantasia(texto)! Nombre de fantasía

Los atributos de texto se combinan con OR de bit usando las constantes de FiscalTextAttr:

! Ejemplo: texto centrado y negritaattr = FiscalAttr_Centered |: FiscalAttr_Bold
oOrch.ZonaHead('MI EMPRESA S.A.', attr)

Ejecución

oOrch.Run()! Abre ventana de progreso y ejecuta toda la cola de comandos

Run() muestra una ventana modal con:

  • Lista de comandos pendientes / ejecutados
  • Barra animada de progreso (PulseBarClass) durante reintentos
  • Botón cancelar (pregunta confirmación antes de abortar)

Ventana de progreso del orquestador

Cancelación

oOrch.Cancelar()! Cancela la operación en curso en el controlador
oOrch.AskAbort()! Pide confirmación al usuario antes de cancelar

9. Tipos y enumeraciones (FiscalTypes)

Todas las constantes están definidas en FiscalTypes.inc.

Tipos de controlador (Fiscal_Type)

Fiscal_TM2000AF ! Epson TM-2000AF
Fiscal_TM2000AFplus! Epson TM-2000AF+Fiscal_TMU220AF ! Epson TM-U220AFFiscal_ND_3 ! Genérico N/A-3Fiscal_ND_5 ! Genérico N/A-5Fiscal_LX300 ! Epson LX-300Fiscal_Hasar_441 ! Hasar 441Fiscal_Hasar_1000 ! Hasar 1000

Tipos de documento (FiscalDocType)

Doc_FacturaA  Doc_FacturaB Doc_FacturaC
Doc_NotaDeCreditoA  Doc_NotaDeCreditoB Doc_NotaDeCreditoC
Doc_NotaDeDebitoA  Doc_NotaDeDebitoB Doc_NotaDeDebitoC
Doc_ReciboA  Doc_ReciboB Doc_ReciboC
Doc_TiqueFacturaA  Doc_TiqueFacturaB Doc_TiqueFacturaC
Doc_TiqueNotaCreditoDoc_InformeDiarioDeCierre ! Cierre ZDoc_DetalleDeVentas ! Informe XDoc_Remito  Doc_Presupuesto Doc_MensajeCF
Doc_ComprobanteDonacion! ... y más de 40 tipos en total

Condición IVA del ítem (FiscalIVACond)

IVA_GravadoIVA_ExentoIVA_NoGravado

Responsabilidad IVA del emisor/receptor (FiscalCondIVA)

IVA_ResponsableInscriptoIVA_ExentoIVA_NoResponsableIVA_MonotributoIVA_ResponsableMonotributoIVA_GranContribuyenteIVA_Consumidor_Final

Medios de pago (FiscalPayment)

Pay_Efectivo  Pay_Cheque
Pay_TarjetaCredito  Pay_TarjetaDebito
Pay_TransferenciaBancaria Pay_CuentaCorriente
Pay_Vales  Pay_Otro
! ... más de 30 tipos

Tipos de impuesto adicional (FiscalTaxType)

Tax_Nacional  Tax_Provincial Tax_Municipal
Tax_Interno  Tax_IIBB Tax_PercepcionIVA

Atributos de texto (FiscalTextAttr) — flags de bit

FiscalAttr_Deleted =01H! TachadoFiscalAttr_Wide =02H! Ancho dobleFiscalAttr_Centered =04H! CentradoFiscalAttr_Bold =08H! Negrita

Estaciones de impresión (FiscalStation)

Station_TicketStation_SlipStation_Default

Zonas del comprobante (FiscalZone)

Zone_Fantasia ! Nombre de fantasíaZone_Domicilio ! Domicilio del emisorZone_Header1 ! Encabezado línea 1Zone_Header2 ! Encabezado línea 2Zone_Footer1 ! Pie línea 1Zone_Footer2 ! Pie línea 2

10. Manejo de errores (FiscalErrors)

Flags de estado (combinables con OR de bit)

FISCAL_OK =000H! Sin erroresFISCAL_ERROR =001H! Error genéricoFISCAL_PRINTER_ERROR =002H! Error físico de impresoraFISCAL_SYNTAX_ERROR =004H! Error de sintaxis de comandoFISCAL_NET_ERROR =008H! Error de red/HTTPFISCAL_BUSY =010H! Controlador ocupadoFISCAL_RESPONSE_ERROR =020H! Respuesta inesperadaFISCAL_UNKNOWN =040H! Estado desconocidoFISCAL_UNKNOWN_COMMAND =080H! Comando no reconocidoFISCAL_AUX =100H! Mensaje auxiliarFISCAL_INTERNAL =200H! Error interno del controlador

Categorías de mensajes del controlador

Los mensajes del controlador están catalogados en rangos numéricos:

RangoCategoría
101–116FISCAL_PRINTER_ERROR — Error físico de impresora
201–216FISCAL_ERROR — Error fiscal/lógico
301–307FISCAL_AUX — Mensajes auxiliares informativos
400–417FISCAL_INTERNAL — Errores internos del controlador

Consulta de descripción de error

desc = oErrors.GetErrorDesc(codigo)! Retorna descripción en español

FiscalErrors contiene un catálogo de más de 200 códigos de error clasificados en categorías: Sistema, E/S, Socket, XML, JSON, Criptografía, Imagen, POS, Auditoría, Memoria Fiscal, Aritmética, Base de Datos, Protocolo e Interfaz.


11. Logging (FiscalLog)

El sistema de logging registra todos los comandos enviados y respuestas recibidas.

Configuración

! Habilitar via variable de entorno (ZVar_GetAndSet)
ZVar_GetAndSet('Fiscal.Log',1)! 1 = activo, 0 = inactivo! O directamente via FiscalConfig:
oConfig.SetLogEnable(1)
oConfig.SetLogFilename('C:\Logs\fiscal')

Nombre del archivo de log

{ruta_base}_{serie}_{YYYY}_{MM}.log
Ejemplo: C:\Logs\fiscal_A12345678_2026_04.log

Formato de entrada

[2026-04-24 14:32:10] → {"AbrirComprobante":{...}}
[2026-04-24 14:32:11] ← {"AbrirComprobante":{"Secuencia":"12345",...}}

Uso programático (raramente necesario directamente)

oLog.Init(oConfig)
oLog.Write('Mensaje de texto plano')
oLog.Write(cstring_var)

Los comandos de FiscalCommand llaman a FiscalLog automáticamente en cada envío/respuesta.


12. Protocolo JSON

Formato de solicitud

{
"NombreComando": {
"Parametro1": "valor1",
"Parametro2": "valor2"
}
}

Formato de respuesta — Éxito

{
"NombreComando": {
"Secuencia": "12345",
"Estado": {
"Impresora": ["estado1", "estado2"],
"Fiscal": ["estadoFiscal1"]
},
"CamposEspecificos": "..."
}
}

Formato de respuesta — Controlador ocupado

{
"ControladorOcupado": {
"Secuencia": "12345",
"Estado": { ... }
}
}

Cuando el controlador responde ControladorOcupado, FiscalCommand entra en bucle de reintento automático. La frecuencia y cantidad de reintentos son configurables. Durante la espera, se invoca el callback MyNotifyClass que activa la animación de PulseBarClass.

Formato de respuesta — Error

{
"Error": {
"Identificador": "CODIGO_ERROR",
"Descripcion": "Descripción del error",
"Contexto": "Información adicional"
}
}

13. Flujo de trabajo completo

Ejemplo mínimo: Factura B

! 1. Crear y configurar el coordinador de conexión
oFiscal.SetPDF(idPuntDeVenta)
oFiscal.SetConnectionString(connStr)IF NOT oFiscal.Open()Message('Error al conectar con el controlador fiscal')RETURNEND! 2. Crear el orquestador
oOrch.Init('Emisión Factura B')! 3. Datos del receptor
oOrch.Cliente('20304050607','Juan Perez','Av. Corrientes 1234', IVA_Consumidor_Final)! 4. Tipo de comprobante
oOrch.Titulo(Doc_FacturaB,1,'')! 5. Ítems
oOrch.Item('Producto A',2,1500.00, IVA_Gravado,21.00,'001')
oOrch.Item('Producto B',1,800.50, IVA_Gravado,10.50,'002')! 6. Pago
oOrch.Pago(Pay_Efectivo,3800.50,'')! 7. Cerrar el comprobante
oOrch.Cierre()! 8. Ejecutar (muestra ventana de progreso)
oOrch.Run()

Ejemplo: Cierre Z diario

! Solo ejecutar si se confirmó con el operadorIFMessage('¿Confirma el Cierre Z?','Cierre Diario',BUTTON:YesNo)=BUTTON:Yes
oCierreZ.Init(oConfig)IF oCierreZ.Run()= FISCAL_OK
Message('Cierre Z N° '& oCierreZ.GetNroZ()&' realizado correctamente.')ELSEMessage('Error en Cierre Z: '& oCierreZ.GetLastError())ENDEND

Ejemplo: Auditoría por fecha

 oAudit.Init(oConfig)
oAudit.SetFechaDesde('20260101')
oAudit.SetFechaHasta('20260131')IF oAudit.Run()<> FISCAL_OK
Message('Error de auditoría: '& oAudit.GetLastError())END

14. Referencia de bases de datos

Tabla pdf_config

CampoTipoDescripción
id_pdfLONGIdentificador del punto de venta
ipSTRINGIP del controlador fiscal (ej: "192.168.1.50")

Tabla pdf_fiscales

CampoTipoDescripción
serieSTRINGNúmero de serie del controlador
prefijoSTRINGPrefijo del punto de venta (ej: "0001")
marcaLONG1=Epson, 2=Hasar, 9=Virtual
modeloLONGConstante Fiscal_Type (ver sección 9)
if_ncLONGFlag de notas de crédito

Consultas ejecutadas por FiscalClass

-- LoadIP()SELECT ip FROM pdf_config WHERE id_pdf = :pdf
-- LoadParams() (tras obtener serial del controlador)SELECT prefijo, marca, modelo, if_nc
FROM pdf_fiscales
WHERE serie = :serial

Versión

La constante FISCAL_VERSION (definida en FiscalTypes.inc) identifica la versión de la biblioteca.

Formato:YY.MM.DDX

ParteDescripciónEjemplo
YYAño (2 dígitos)26
MMMes (2 dígitos)04
DDDía (2 dígitos)25
XRevisión del día (letra: A, B, C…)A

Historial

VersiónCambios
26.04.25APrimera versión pública

Notas para el desarrollador

  • Nunca instanciar FiscalConfig directamente: es un singleton. Acceder siempre a través de su instancia global.
  • El Cierre Z es irreversible: validar siempre con el operador antes de ejecutarlo.
  • LibCurl debe estar en el PATH o en la carpeta del ejecutable: sin él, todos los comandos fallan con HTTP:CURL_ERROR.
  • El logging crea un archivo por mes: monitorear espacio en disco en instalaciones con alto volumen de comprobantes.
  • FiscalOrchestra.Run() es bloqueante: abre una ventana modal. Si se necesita integración en un proceso batch sin UI, ejecutar los comandos directamente vía sus clases concretas.
  • Reintentos por ControladorOcupado: el controlador puede estar procesando un trabajo anterior. FiscalCommand reintenta automáticamente; el desarrollador puede configurar el número de intentos y el delay entre ellos.

About

Hasar Fiscal Printer Driver

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - gsaracca/FiscalClass: Hasar Fiscal Printer Driver · GitHub
Skip to content

Latest commit

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

FiscalClass — Biblioteca Clarion para Controladores Fiscales

Biblioteca de clases Clarion para integración con controladores fiscales electrónicos argentinos. Gestiona la comunicación HTTP/JSON con la impresora, el ciclo de vida completo de comprobantes (facturas, notas de crédito, cierres), auditoría y logging.

Autor: Gustavo Saracca
Plataforma: Clarion (CLW/INC)
Contacto:gsaracca@gmail.comPaís: Argentina — Controladores fiscales homologados AFIP
Licencia:MIT


Índice

  1. Requisitos y dependencias
  2. Estructura de archivos
  3. Arquitectura general
  4. Configuración inicial (FiscalConfig)
  5. Inicialización de conexión (FiscalClass)
  6. Capa de transporte HTTP (FiscalHTTP)
  7. Comandos disponibles
  8. Orquestador de documentos (FiscalOrchestra)
  9. Tipos y enumeraciones (FiscalTypes)
  10. Manejo de errores (FiscalErrors)
  11. Logging (FiscalLog)
  12. Protocolo JSON
  13. Flujo de trabajo completo
  14. Referencia de bases de datos

1. Requisitos y dependencias

Bibliotecas externas requeridas

ArchivoPropósito
LibCurl.inc / LibCurl.libComunicación HTTP (POST al controlador fiscal)
cJson.inc / cJson.libSerialización/deserialización JSON
..\access\access.libUtilidades de base de datos y presentación de mensajes
..\group\group.libGestión de variables globales (ZVar_GetAndSet)

Wrapper Clarion para la biblioteca libcurl, que permite realizar peticiones HTTP/HTTPS desde código Clarion nativo. FiscalClass la utiliza a través de TCurlClass para enviar los comandos JSON al controlador fiscal mediante HTTP POST al endpoint http://<ip>/fiscal.json. Es un requisito indispensable: sin esta biblioteca, todos los comandos fallan con HTTP:CURL_ERROR.

La DLL libcurl.dll debe estar disponible en el PATH del sistema o en la carpeta del ejecutable.

Wrapper Clarion para el parser cJSON, que provee serialización y deserialización de documentos JSON. FiscalClass lo utiliza para construir los payloads de cada comando (solicitudes) y para interpretar las respuestas del controlador fiscal (éxito, error, ControladorOcupado). Sin esta biblioteca no es posible comunicarse con el controlador, ya que el protocolo completo está basado en JSON.

Variables globales requeridas (via ZVar_GetAndSet)

VariableTipoDescripción
Fiscal.LogLONG1 = logging habilitado, 0 = deshabilitado

Tabla SQL requerida: pdf_config

-- Mapea cada punto de venta (PDF) a la IP del controlador fiscal
pdf_config (
id_pdf -- Identificador del punto de venta
ip -- Dirección IP del controlador fiscal (ej: "192.168.1.50")
)

Tabla SQL requerida: pdf_fiscales

-- Mapea el número de serie fiscal a configuración del punto de venta
pdf_fiscales (
serie -- Número de serie del controlador (ej: "A12345678")
prefijo -- Prefijo del comprobante (ej: "0001")
marca -- 1=Epson, 2=Hasar, 9=Virtual
modelo -- Ver enumeración Fiscal_Type en FiscalTypes.inc
if_nc -- Flag notas de crédito
)

2. Estructura de archivos

FiscalClass/
│
├── FiscalTypes.inc ← Enumeraciones y constantes globales
│
├── FiscalConfig.clw / .inc ← Singleton de configuración global
├── FiscalLog.clw / .inc ← Subsistema de logging
├── FiscalErrors.clw / .inc ← Registro de códigos de error
├── FiscalTools.clw / .inc ← Utilidades (zonas, flags de texto)
│
├── FiscalHTTP.clw / .inc ← Capa HTTP con LibCurl
├── FiscalCommand.clw / .inc ← Clase base de comandos + lógica de reintentos
│
├── FiscalClass.clw / .inc ← Coordinador principal (conexión, inicialización)
│
│ ── Comandos específicos ──
├── FiscalInicializacion.clw / .inc ← Consulta datos del controlador
├── FiscalConsultarEstado.clw / .inc ← Estado actual del controlador
├── FiscalCancelar.clw / .inc ← Cancelar operación en curso
├── FiscalCierreX.clw / .inc ← Informe X (subtotal sin borrar)
├── FiscalCierreZ.clw / .inc ← Cierre Z (cierre diario definitivo)
├── FiscalAuditDate.clw / .inc ← Auditoría por rango de fechas
├── FiscalAuditNumber.clw / .inc ← Auditoría por rango de número Z
├── FiscalCopiarComprobante.clw / .inc← Reimpresión de comprobante
│
├── FiscalOrchestra.clw / .inc ← Orquestador de alto nivel (workflow completo)
├── FiscalMail.clw ← Envío de documentos por correo
│
└── PulseBarClass.clw / .inc ← Control visual de progreso (barra animada)

3. Arquitectura general

La biblioteca está organizada en capas bien definidas:

┌─────────────────────────────────────────────────────┐
│ FiscalOrchestra │ ← Capa de aplicación
│ (workflow, UI, cola de comandos) │
└─────────────────┬───────────────────────────────────┘
│ usa
┌─────────────────▼───────────────────────────────────┐
│ FiscalInicializacion FiscalCierreZ FiscalCierreX │ ← Comandos concretos
│ FiscalConsultarEstado FiscalCancelar FiscalAudit… │
└─────────────────┬───────────────────────────────────┘
│ heredan
┌─────────────────▼───────────────────────────────────┐
│ FiscalCommand / FiscalCommandClass │ ← Base: JSON + reintentos
└─────────────────┬───────────────────────────────────┘
│ hereda
┌─────────────────▼───────────────────────────────────┐
│ FiscalHTTP │ ← HTTP POST via LibCurl
└─────────────────────────────────────────────────────┘
Transversal a todas las capas:
FiscalConfig (singleton de configuración)
FiscalLog (logging a archivo)
FiscalErrors (catálogo de errores)

Jerarquía de herencia de clases

FiscalHTTP
└─ FiscalCommandClass
└─ FiscalCommand (wrapper con reintentos automáticos)
├─ FiscalInicializacion
├─ FiscalConsultarEstado
├─ FiscalCancelar
├─ FiscalCierreX
├─ FiscalCierreZ
├─ FiscalAuditDate
├─ FiscalAuditNumber
└─ FiscalCopiarComprobante

4. Configuración inicial (FiscalConfig)

FiscalConfig es un objeto global singleton (instancia única compartida). No debe ser instanciado manualmente; se accede a través de su instancia global.

Propiedades configurables

MétodoDescripción
SetIP(string)IP del controlador fiscal
SetSerial(string)Número de serie del controlador
SetMarca(long)Marca: 1=Epson, 2=Hasar, 9=Virtual
SetModelo(long)Modelo (ver Fiscal_Type en FiscalTypes.inc)
SetPrefijo(string)Prefijo del punto de venta (ej: "0001")
SetNC(long)Flag notas de crédito
SetIIBB(string)Número de inscripción IIBB
SetCondIVA(long)Condición frente al IVA
SetLogEnable(long)Habilitar/deshabilitar logging
SetLogFilename(string)Ruta base del archivo de log
SetMsgBox(long)Controla presentación de mensajes

Mapeo de marca a string

1 → "Epson"
2 → "Hasar"
9 → "Virtual"

Mapeo de modelo a string

Fiscal_TM2000AF → "TM2000AF"
Fiscal_TM2000AFplus→ "TM2000AF+"
Fiscal_TMU220AF → "TMU220AF"
Fiscal_ND_3 → "N/A-3"
Fiscal_ND_5 → "N/A-5"
Fiscal_LX300 → "LX-300"
Fiscal_Hasar_441 → "441"
Fiscal_Hasar_1000 → "1000"

5. Inicialización de conexión (FiscalClass)

FiscalClass coordina la inicialización completa leyendo la configuración desde la base de datos.

Métodos principales

MétodoDescripción
SetPDF(long)Define el ID del punto de venta
SetConnectionString(string)Cadena de conexión SQL
Open()Ejecuta el flujo completo de inicialización
LoadIP()Lee la IP desde pdf_config
LoadFiscal()Consulta el controlador y carga serial/prefijo
LoadParams()Lee marca y modelo desde pdf_fiscales

Flujo de Open()

Open()
├─ LoadIP() → Lee ip de pdf_config WHERE id_pdf = @pdf
├─ LoadFiscal() → Ejecuta FiscalInicializacion, guarda serial/prefijo
└─ LoadParams() → Lee marca/modelo de pdf_fiscales WHERE serie = @serial

Atributos disponibles tras Open()

oFiscal.GetPDF()! ID del punto de venta
oFiscal.GetPrefijo()! Prefijo cargado desde controlador
oFiscal.GetConfigPrefijo()! Prefijo cargado desde base de datos

6. Capa de transporte HTTP (FiscalHTTP)

FiscalHTTP encapsula la comunicación HTTP POST usando TCurlClass (LibCurl).

Endpoint

POST http://<ip>/fiscal.json
Content-Type: application/json

Atributos de resultado

AtributoDescripción
HTTPCodeCódigo de respuesta HTTP
HTTPMessageCuerpo de la respuesta (JSON)
HTTPErrorCódigo de error interno

Códigos de error HTTP internos

HTTP:CURL_OK =0! ExitosoHTTP:CURL_ERROR =1! Error de LibCurlHTTP:NET_ERROR =2! Respuesta HTTP 3xx-5xx

7. Comandos disponibles

Todos los comandos heredan de FiscalCommand e implementan el método Run().

7.1 FiscalInicializacion

Consulta los datos de identificación del controlador fiscal.

Respuesta relevante:

  • CUIT del emisor
  • Razón social
  • Número de serie
  • Prefijo del punto de venta
oInit.Init(oConfig)IF oInit.Run()= FISCAL_OK
serial = oInit.GetSerial()
prefijo = oInit.GetPrefijo()
cuit = oInit.GetCUIT()END

7.2 FiscalConsultarEstado

Obtiene el estado actual del controlador y el último comprobante emitido.

oEstado.Init(oConfig)IF oEstado.Run()= FISCAL_OK
estado = oEstado.GetEstado()
ultimo = oEstado.GetUltimoComprobante()END

7.3 FiscalCancelar

Cancela la operación en curso en el controlador.

oCancel.Init(oConfig)
oCancel.Run()

7.4 FiscalCierreX — Informe X

Emite un informe de subtotales sin borrar la memoria fiscal. Equivale a un "corte X" en terminología fiscal.

oCierreX.Init(oConfig)IF oCierreX.Run()= FISCAL_OK
! Informe impreso en el controladorEND

7.5 FiscalCierreZ — Cierre diario

Emite el cierre diario definitivo. Borra los acumuladores y avanza el contador Z.

oCierreZ.Init(oConfig)IF oCierreZ.Run()= FISCAL_OK
nroZ = oCierreZ.GetNroZ()
totalZ = oCierreZ.GetTotal()END

Importante: Esta operación es irreversible. El controlador fiscal homologado no permite anular un cierre Z.

7.6 FiscalAuditDate — Auditoría por fecha

Imprime el informe de auditoría para un rango de fechas.

oAudit.Init(oConfig)
oAudit.SetFechaDesde('20260101')
oAudit.SetFechaHasta('20260131')
oAudit.Run()

7.7 FiscalAuditNumber — Auditoría por número Z

Imprime el informe de auditoría para un rango de números de cierre Z.

oAuditN.Init(oConfig)
oAuditN.SetZDesde(100)
oAuditN.SetZHasta(150)
oAuditN.Run()

7.8 FiscalCopiarComprobante

Reimprime una copia de un comprobante emitido.

oCopia.Init(oConfig)
oCopia.SetNumeroComprobante(12345)
oCopia.Run()

8. Orquestador de documentos (FiscalOrchestra)

FiscalOrchestra es el componente de más alto nivel. Gestiona el ciclo de vida completo de un comprobante fiscal, acumulando comandos en una cola y ejecutándolos con una UI de progreso.

Inicialización

oOrch.Init('Emisión Factura B')! Título visible en la ventana de progreso
oOrch.SetConfig(oConfig)

Métodos de construcción del documento

Cliente (datos del receptor)

oOrch.Cliente(
cuit,! CUIT del cliente (string, sin guiones)
razonSocial,! Razón social o nombre
domicilio,! Domicilio completo
condIVA ! Ver FiscalCondIVA en FiscalTypes.inc)

Título (cabecera del comprobante)

oOrch.Titulo(
tipoDoc,! Ver FiscalDocType en FiscalTypes.inc (ej: Doc_FacturaB)
copias,! Cantidad de copias a imprimir
referencia ! Número de comprobante de referencia (para NC/ND))

Ítem (líneas del cuerpo)

oOrch.Item(
descripcion,! Texto de la línea
cantidad,! Cantidad (DECIMAL)
precioUnitario,! Precio unitario (DECIMAL)
ivaCondicion,! Ver FiscalIVACond (Gravado, Exento, NoGravado)
ivaAlicuota,! Alícuota de IVA (ej: 21.00)
codigoProducto ! Código interno del producto)

Pago

oOrch.Pago(
medioPago,! Ver FiscalPayment en FiscalTypes.inc
importe,! Importe del pago (DECIMAL)
descripcion ! Descripción opcional)

Percepción

oOrch.Percepcion(
tipoImpuesto,! Ver FiscalTaxType
alicuota,! Alícuota
importe ! Importe percibido)

Bonificación / Descuento

oOrch.Bonif(
descripcion,
importe,! Positivo = descuento, negativo = recargo
ivaCondicion
)

Ajuste

oOrch.Ajuste(descripcion, importe)

Cierre del comprobante

oOrch.Cierre()

Sección no fiscal (textos sin efecto fiscal)

oOrch.TituloNF(texto)! Título de sección no fiscal
oOrch.TextoNF(texto)! Línea de texto libre
oOrch.CierreNF()! Cierre de sección no fiscal

Zonas de texto (header/footer del comprobante)

oOrch.ZonaHead(texto, atributos)! Encabezado del ticket
oOrch.ZonaFoot(texto, atributos)! Pie del ticket
oOrch.ZonaDomicilioEmisor(texto)! Domicilio del emisor
oOrch.ZonaFantasia(texto)! Nombre de fantasía

Los atributos de texto se combinan con OR de bit usando las constantes de FiscalTextAttr:

! Ejemplo: texto centrado y negritaattr = FiscalAttr_Centered |: FiscalAttr_Bold
oOrch.ZonaHead('MI EMPRESA S.A.', attr)

Ejecución

oOrch.Run()! Abre ventana de progreso y ejecuta toda la cola de comandos

Run() muestra una ventana modal con:

  • Lista de comandos pendientes / ejecutados
  • Barra animada de progreso (PulseBarClass) durante reintentos
  • Botón cancelar (pregunta confirmación antes de abortar)

Ventana de progreso del orquestador

Cancelación

oOrch.Cancelar()! Cancela la operación en curso en el controlador
oOrch.AskAbort()! Pide confirmación al usuario antes de cancelar

9. Tipos y enumeraciones (FiscalTypes)

Todas las constantes están definidas en FiscalTypes.inc.

Tipos de controlador (Fiscal_Type)

Fiscal_TM2000AF ! Epson TM-2000AF
Fiscal_TM2000AFplus! Epson TM-2000AF+Fiscal_TMU220AF ! Epson TM-U220AFFiscal_ND_3 ! Genérico N/A-3Fiscal_ND_5 ! Genérico N/A-5Fiscal_LX300 ! Epson LX-300Fiscal_Hasar_441 ! Hasar 441Fiscal_Hasar_1000 ! Hasar 1000

Tipos de documento (FiscalDocType)

Doc_FacturaA  Doc_FacturaB Doc_FacturaC
Doc_NotaDeCreditoA  Doc_NotaDeCreditoB Doc_NotaDeCreditoC
Doc_NotaDeDebitoA  Doc_NotaDeDebitoB Doc_NotaDeDebitoC
Doc_ReciboA  Doc_ReciboB Doc_ReciboC
Doc_TiqueFacturaA  Doc_TiqueFacturaB Doc_TiqueFacturaC
Doc_TiqueNotaCreditoDoc_InformeDiarioDeCierre ! Cierre ZDoc_DetalleDeVentas ! Informe XDoc_Remito  Doc_Presupuesto Doc_MensajeCF
Doc_ComprobanteDonacion! ... y más de 40 tipos en total

Condición IVA del ítem (FiscalIVACond)

IVA_GravadoIVA_ExentoIVA_NoGravado

Responsabilidad IVA del emisor/receptor (FiscalCondIVA)

IVA_ResponsableInscriptoIVA_ExentoIVA_NoResponsableIVA_MonotributoIVA_ResponsableMonotributoIVA_GranContribuyenteIVA_Consumidor_Final

Medios de pago (FiscalPayment)

Pay_Efectivo  Pay_Cheque
Pay_TarjetaCredito  Pay_TarjetaDebito
Pay_TransferenciaBancaria Pay_CuentaCorriente
Pay_Vales  Pay_Otro
! ... más de 30 tipos

Tipos de impuesto adicional (FiscalTaxType)

Tax_Nacional  Tax_Provincial Tax_Municipal
Tax_Interno  Tax_IIBB Tax_PercepcionIVA

Atributos de texto (FiscalTextAttr) — flags de bit

FiscalAttr_Deleted =01H! TachadoFiscalAttr_Wide =02H! Ancho dobleFiscalAttr_Centered =04H! CentradoFiscalAttr_Bold =08H! Negrita

Estaciones de impresión (FiscalStation)

Station_TicketStation_SlipStation_Default

Zonas del comprobante (FiscalZone)

Zone_Fantasia ! Nombre de fantasíaZone_Domicilio ! Domicilio del emisorZone_Header1 ! Encabezado línea 1Zone_Header2 ! Encabezado línea 2Zone_Footer1 ! Pie línea 1Zone_Footer2 ! Pie línea 2

10. Manejo de errores (FiscalErrors)

Flags de estado (combinables con OR de bit)

FISCAL_OK =000H! Sin erroresFISCAL_ERROR =001H! Error genéricoFISCAL_PRINTER_ERROR =002H! Error físico de impresoraFISCAL_SYNTAX_ERROR =004H! Error de sintaxis de comandoFISCAL_NET_ERROR =008H! Error de red/HTTPFISCAL_BUSY =010H! Controlador ocupadoFISCAL_RESPONSE_ERROR =020H! Respuesta inesperadaFISCAL_UNKNOWN =040H! Estado desconocidoFISCAL_UNKNOWN_COMMAND =080H! Comando no reconocidoFISCAL_AUX =100H! Mensaje auxiliarFISCAL_INTERNAL =200H! Error interno del controlador

Categorías de mensajes del controlador

Los mensajes del controlador están catalogados en rangos numéricos:

RangoCategoría
101–116FISCAL_PRINTER_ERROR — Error físico de impresora
201–216FISCAL_ERROR — Error fiscal/lógico
301–307FISCAL_AUX — Mensajes auxiliares informativos
400–417FISCAL_INTERNAL — Errores internos del controlador

Consulta de descripción de error

desc = oErrors.GetErrorDesc(codigo)! Retorna descripción en español

FiscalErrors contiene un catálogo de más de 200 códigos de error clasificados en categorías: Sistema, E/S, Socket, XML, JSON, Criptografía, Imagen, POS, Auditoría, Memoria Fiscal, Aritmética, Base de Datos, Protocolo e Interfaz.


11. Logging (FiscalLog)

El sistema de logging registra todos los comandos enviados y respuestas recibidas.

Configuración

! Habilitar via variable de entorno (ZVar_GetAndSet)
ZVar_GetAndSet('Fiscal.Log',1)! 1 = activo, 0 = inactivo! O directamente via FiscalConfig:
oConfig.SetLogEnable(1)
oConfig.SetLogFilename('C:\Logs\fiscal')

Nombre del archivo de log

{ruta_base}_{serie}_{YYYY}_{MM}.log
Ejemplo: C:\Logs\fiscal_A12345678_2026_04.log

Formato de entrada

[2026-04-24 14:32:10] → {"AbrirComprobante":{...}}
[2026-04-24 14:32:11] ← {"AbrirComprobante":{"Secuencia":"12345",...}}

Uso programático (raramente necesario directamente)

oLog.Init(oConfig)
oLog.Write('Mensaje de texto plano')
oLog.Write(cstring_var)

Los comandos de FiscalCommand llaman a FiscalLog automáticamente en cada envío/respuesta.


12. Protocolo JSON

Formato de solicitud

{
"NombreComando": {
"Parametro1": "valor1",
"Parametro2": "valor2"
}
}

Formato de respuesta — Éxito

{
"NombreComando": {
"Secuencia": "12345",
"Estado": {
"Impresora": ["estado1", "estado2"],
"Fiscal": ["estadoFiscal1"]
},
"CamposEspecificos": "..."
}
}

Formato de respuesta — Controlador ocupado

{
"ControladorOcupado": {
"Secuencia": "12345",
"Estado": { ... }
}
}

Cuando el controlador responde ControladorOcupado, FiscalCommand entra en bucle de reintento automático. La frecuencia y cantidad de reintentos son configurables. Durante la espera, se invoca el callback MyNotifyClass que activa la animación de PulseBarClass.

Formato de respuesta — Error

{
"Error": {
"Identificador": "CODIGO_ERROR",
"Descripcion": "Descripción del error",
"Contexto": "Información adicional"
}
}

13. Flujo de trabajo completo

Ejemplo mínimo: Factura B

! 1. Crear y configurar el coordinador de conexión
oFiscal.SetPDF(idPuntDeVenta)
oFiscal.SetConnectionString(connStr)IF NOT oFiscal.Open()Message('Error al conectar con el controlador fiscal')RETURNEND! 2. Crear el orquestador
oOrch.Init('Emisión Factura B')! 3. Datos del receptor
oOrch.Cliente('20304050607','Juan Perez','Av. Corrientes 1234', IVA_Consumidor_Final)! 4. Tipo de comprobante
oOrch.Titulo(Doc_FacturaB,1,'')! 5. Ítems
oOrch.Item('Producto A',2,1500.00, IVA_Gravado,21.00,'001')
oOrch.Item('Producto B',1,800.50, IVA_Gravado,10.50,'002')! 6. Pago
oOrch.Pago(Pay_Efectivo,3800.50,'')! 7. Cerrar el comprobante
oOrch.Cierre()! 8. Ejecutar (muestra ventana de progreso)
oOrch.Run()

Ejemplo: Cierre Z diario

! Solo ejecutar si se confirmó con el operadorIFMessage('¿Confirma el Cierre Z?','Cierre Diario',BUTTON:YesNo)=BUTTON:Yes
oCierreZ.Init(oConfig)IF oCierreZ.Run()= FISCAL_OK
Message('Cierre Z N° '& oCierreZ.GetNroZ()&' realizado correctamente.')ELSEMessage('Error en Cierre Z: '& oCierreZ.GetLastError())ENDEND

Ejemplo: Auditoría por fecha

 oAudit.Init(oConfig)
oAudit.SetFechaDesde('20260101')
oAudit.SetFechaHasta('20260131')IF oAudit.Run()<> FISCAL_OK
Message('Error de auditoría: '& oAudit.GetLastError())END

14. Referencia de bases de datos

Tabla pdf_config

CampoTipoDescripción
id_pdfLONGIdentificador del punto de venta
ipSTRINGIP del controlador fiscal (ej: "192.168.1.50")

Tabla pdf_fiscales

CampoTipoDescripción
serieSTRINGNúmero de serie del controlador
prefijoSTRINGPrefijo del punto de venta (ej: "0001")
marcaLONG1=Epson, 2=Hasar, 9=Virtual
modeloLONGConstante Fiscal_Type (ver sección 9)
if_ncLONGFlag de notas de crédito

Consultas ejecutadas por FiscalClass

-- LoadIP()SELECT ip FROM pdf_config WHERE id_pdf = :pdf
-- LoadParams() (tras obtener serial del controlador)SELECT prefijo, marca, modelo, if_nc
FROM pdf_fiscales
WHERE serie = :serial

Versión

La constante FISCAL_VERSION (definida en FiscalTypes.inc) identifica la versión de la biblioteca.

Formato:YY.MM.DDX

ParteDescripciónEjemplo
YYAño (2 dígitos)26
MMMes (2 dígitos)04
DDDía (2 dígitos)25
XRevisión del día (letra: A, B, C…)A

Historial

VersiónCambios
26.04.25APrimera versión pública

Notas para el desarrollador

  • Nunca instanciar FiscalConfig directamente: es un singleton. Acceder siempre a través de su instancia global.
  • El Cierre Z es irreversible: validar siempre con el operador antes de ejecutarlo.
  • LibCurl debe estar en el PATH o en la carpeta del ejecutable: sin él, todos los comandos fallan con HTTP:CURL_ERROR.
  • El logging crea un archivo por mes: monitorear espacio en disco en instalaciones con alto volumen de comprobantes.
  • FiscalOrchestra.Run() es bloqueante: abre una ventana modal. Si se necesita integración en un proceso batch sin UI, ejecutar los comandos directamente vía sus clases concretas.
  • Reintentos por ControladorOcupado: el controlador puede estar procesando un trabajo anterior. FiscalCommand reintenta automáticamente; el desarrollador puede configurar el número de intentos y el delay entre ellos.

About

Hasar Fiscal Printer Driver

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - gsaracca/FiscalClass: Hasar Fiscal Printer Driver · GitHub
Skip to content

Latest commit

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

FiscalClass — Biblioteca Clarion para Controladores Fiscales

Biblioteca de clases Clarion para integración con controladores fiscales electrónicos argentinos. Gestiona la comunicación HTTP/JSON con la impresora, el ciclo de vida completo de comprobantes (facturas, notas de crédito, cierres), auditoría y logging.

Autor: Gustavo Saracca
Plataforma: Clarion (CLW/INC)
Contacto:gsaracca@gmail.comPaís: Argentina — Controladores fiscales homologados AFIP
Licencia:MIT


Índice

  1. Requisitos y dependencias
  2. Estructura de archivos
  3. Arquitectura general
  4. Configuración inicial (FiscalConfig)
  5. Inicialización de conexión (FiscalClass)
  6. Capa de transporte HTTP (FiscalHTTP)
  7. Comandos disponibles
  8. Orquestador de documentos (FiscalOrchestra)
  9. Tipos y enumeraciones (FiscalTypes)
  10. Manejo de errores (FiscalErrors)
  11. Logging (FiscalLog)
  12. Protocolo JSON
  13. Flujo de trabajo completo
  14. Referencia de bases de datos

1. Requisitos y dependencias

Bibliotecas externas requeridas

ArchivoPropósito
LibCurl.inc / LibCurl.libComunicación HTTP (POST al controlador fiscal)
cJson.inc / cJson.libSerialización/deserialización JSON
..\access\access.libUtilidades de base de datos y presentación de mensajes
..\group\group.libGestión de variables globales (ZVar_GetAndSet)

Wrapper Clarion para la biblioteca libcurl, que permite realizar peticiones HTTP/HTTPS desde código Clarion nativo. FiscalClass la utiliza a través de TCurlClass para enviar los comandos JSON al controlador fiscal mediante HTTP POST al endpoint http://<ip>/fiscal.json. Es un requisito indispensable: sin esta biblioteca, todos los comandos fallan con HTTP:CURL_ERROR.

La DLL libcurl.dll debe estar disponible en el PATH del sistema o en la carpeta del ejecutable.

Wrapper Clarion para el parser cJSON, que provee serialización y deserialización de documentos JSON. FiscalClass lo utiliza para construir los payloads de cada comando (solicitudes) y para interpretar las respuestas del controlador fiscal (éxito, error, ControladorOcupado). Sin esta biblioteca no es posible comunicarse con el controlador, ya que el protocolo completo está basado en JSON.

Variables globales requeridas (via ZVar_GetAndSet)

VariableTipoDescripción
Fiscal.LogLONG1 = logging habilitado, 0 = deshabilitado

Tabla SQL requerida: pdf_config

-- Mapea cada punto de venta (PDF) a la IP del controlador fiscal
pdf_config (
id_pdf -- Identificador del punto de venta
ip -- Dirección IP del controlador fiscal (ej: "192.168.1.50")
)

Tabla SQL requerida: pdf_fiscales

-- Mapea el número de serie fiscal a configuración del punto de venta
pdf_fiscales (
serie -- Número de serie del controlador (ej: "A12345678")
prefijo -- Prefijo del comprobante (ej: "0001")
marca -- 1=Epson, 2=Hasar, 9=Virtual
modelo -- Ver enumeración Fiscal_Type en FiscalTypes.inc
if_nc -- Flag notas de crédito
)

2. Estructura de archivos

FiscalClass/
│
├── FiscalTypes.inc ← Enumeraciones y constantes globales
│
├── FiscalConfig.clw / .inc ← Singleton de configuración global
├── FiscalLog.clw / .inc ← Subsistema de logging
├── FiscalErrors.clw / .inc ← Registro de códigos de error
├── FiscalTools.clw / .inc ← Utilidades (zonas, flags de texto)
│
├── FiscalHTTP.clw / .inc ← Capa HTTP con LibCurl
├── FiscalCommand.clw / .inc ← Clase base de comandos + lógica de reintentos
│
├── FiscalClass.clw / .inc ← Coordinador principal (conexión, inicialización)
│
│ ── Comandos específicos ──
├── FiscalInicializacion.clw / .inc ← Consulta datos del controlador
├── FiscalConsultarEstado.clw / .inc ← Estado actual del controlador
├── FiscalCancelar.clw / .inc ← Cancelar operación en curso
├── FiscalCierreX.clw / .inc ← Informe X (subtotal sin borrar)
├── FiscalCierreZ.clw / .inc ← Cierre Z (cierre diario definitivo)
├── FiscalAuditDate.clw / .inc ← Auditoría por rango de fechas
├── FiscalAuditNumber.clw / .inc ← Auditoría por rango de número Z
├── FiscalCopiarComprobante.clw / .inc← Reimpresión de comprobante
│
├── FiscalOrchestra.clw / .inc ← Orquestador de alto nivel (workflow completo)
├── FiscalMail.clw ← Envío de documentos por correo
│
└── PulseBarClass.clw / .inc ← Control visual de progreso (barra animada)

3. Arquitectura general

La biblioteca está organizada en capas bien definidas:

┌─────────────────────────────────────────────────────┐
│ FiscalOrchestra │ ← Capa de aplicación
│ (workflow, UI, cola de comandos) │
└─────────────────┬───────────────────────────────────┘
│ usa
┌─────────────────▼───────────────────────────────────┐
│ FiscalInicializacion FiscalCierreZ FiscalCierreX │ ← Comandos concretos
│ FiscalConsultarEstado FiscalCancelar FiscalAudit… │
└─────────────────┬───────────────────────────────────┘
│ heredan
┌─────────────────▼───────────────────────────────────┐
│ FiscalCommand / FiscalCommandClass │ ← Base: JSON + reintentos
└─────────────────┬───────────────────────────────────┘
│ hereda
┌─────────────────▼───────────────────────────────────┐
│ FiscalHTTP │ ← HTTP POST via LibCurl
└─────────────────────────────────────────────────────┘
Transversal a todas las capas:
FiscalConfig (singleton de configuración)
FiscalLog (logging a archivo)
FiscalErrors (catálogo de errores)

Jerarquía de herencia de clases

FiscalHTTP
└─ FiscalCommandClass
└─ FiscalCommand (wrapper con reintentos automáticos)
├─ FiscalInicializacion
├─ FiscalConsultarEstado
├─ FiscalCancelar
├─ FiscalCierreX
├─ FiscalCierreZ
├─ FiscalAuditDate
├─ FiscalAuditNumber
└─ FiscalCopiarComprobante

4. Configuración inicial (FiscalConfig)

FiscalConfig es un objeto global singleton (instancia única compartida). No debe ser instanciado manualmente; se accede a través de su instancia global.

Propiedades configurables

MétodoDescripción
SetIP(string)IP del controlador fiscal
SetSerial(string)Número de serie del controlador
SetMarca(long)Marca: 1=Epson, 2=Hasar, 9=Virtual
SetModelo(long)Modelo (ver Fiscal_Type en FiscalTypes.inc)
SetPrefijo(string)Prefijo del punto de venta (ej: "0001")
SetNC(long)Flag notas de crédito
SetIIBB(string)Número de inscripción IIBB
SetCondIVA(long)Condición frente al IVA
SetLogEnable(long)Habilitar/deshabilitar logging
SetLogFilename(string)Ruta base del archivo de log
SetMsgBox(long)Controla presentación de mensajes

Mapeo de marca a string

1 → "Epson"
2 → "Hasar"
9 → "Virtual"

Mapeo de modelo a string

Fiscal_TM2000AF → "TM2000AF"
Fiscal_TM2000AFplus→ "TM2000AF+"
Fiscal_TMU220AF → "TMU220AF"
Fiscal_ND_3 → "N/A-3"
Fiscal_ND_5 → "N/A-5"
Fiscal_LX300 → "LX-300"
Fiscal_Hasar_441 → "441"
Fiscal_Hasar_1000 → "1000"

5. Inicialización de conexión (FiscalClass)

FiscalClass coordina la inicialización completa leyendo la configuración desde la base de datos.

Métodos principales

MétodoDescripción
SetPDF(long)Define el ID del punto de venta
SetConnectionString(string)Cadena de conexión SQL
Open()Ejecuta el flujo completo de inicialización
LoadIP()Lee la IP desde pdf_config
LoadFiscal()Consulta el controlador y carga serial/prefijo
LoadParams()Lee marca y modelo desde pdf_fiscales

Flujo de Open()

Open()
├─ LoadIP() → Lee ip de pdf_config WHERE id_pdf = @pdf
├─ LoadFiscal() → Ejecuta FiscalInicializacion, guarda serial/prefijo
└─ LoadParams() → Lee marca/modelo de pdf_fiscales WHERE serie = @serial

Atributos disponibles tras Open()

oFiscal.GetPDF()! ID del punto de venta
oFiscal.GetPrefijo()! Prefijo cargado desde controlador
oFiscal.GetConfigPrefijo()! Prefijo cargado desde base de datos

6. Capa de transporte HTTP (FiscalHTTP)

FiscalHTTP encapsula la comunicación HTTP POST usando TCurlClass (LibCurl).

Endpoint

POST http://<ip>/fiscal.json
Content-Type: application/json

Atributos de resultado

AtributoDescripción
HTTPCodeCódigo de respuesta HTTP
HTTPMessageCuerpo de la respuesta (JSON)
HTTPErrorCódigo de error interno

Códigos de error HTTP internos

HTTP:CURL_OK =0! ExitosoHTTP:CURL_ERROR =1! Error de LibCurlHTTP:NET_ERROR =2! Respuesta HTTP 3xx-5xx

7. Comandos disponibles

Todos los comandos heredan de FiscalCommand e implementan el método Run().

7.1 FiscalInicializacion

Consulta los datos de identificación del controlador fiscal.

Respuesta relevante:

  • CUIT del emisor
  • Razón social
  • Número de serie
  • Prefijo del punto de venta
oInit.Init(oConfig)IF oInit.Run()= FISCAL_OK
serial = oInit.GetSerial()
prefijo = oInit.GetPrefijo()
cuit = oInit.GetCUIT()END

7.2 FiscalConsultarEstado

Obtiene el estado actual del controlador y el último comprobante emitido.

oEstado.Init(oConfig)IF oEstado.Run()= FISCAL_OK
estado = oEstado.GetEstado()
ultimo = oEstado.GetUltimoComprobante()END

7.3 FiscalCancelar

Cancela la operación en curso en el controlador.

oCancel.Init(oConfig)
oCancel.Run()

7.4 FiscalCierreX — Informe X

Emite un informe de subtotales sin borrar la memoria fiscal. Equivale a un "corte X" en terminología fiscal.

oCierreX.Init(oConfig)IF oCierreX.Run()= FISCAL_OK
! Informe impreso en el controladorEND

7.5 FiscalCierreZ — Cierre diario

Emite el cierre diario definitivo. Borra los acumuladores y avanza el contador Z.

oCierreZ.Init(oConfig)IF oCierreZ.Run()= FISCAL_OK
nroZ = oCierreZ.GetNroZ()
totalZ = oCierreZ.GetTotal()END

Importante: Esta operación es irreversible. El controlador fiscal homologado no permite anular un cierre Z.

7.6 FiscalAuditDate — Auditoría por fecha

Imprime el informe de auditoría para un rango de fechas.

oAudit.Init(oConfig)
oAudit.SetFechaDesde('20260101')
oAudit.SetFechaHasta('20260131')
oAudit.Run()

7.7 FiscalAuditNumber — Auditoría por número Z

Imprime el informe de auditoría para un rango de números de cierre Z.

oAuditN.Init(oConfig)
oAuditN.SetZDesde(100)
oAuditN.SetZHasta(150)
oAuditN.Run()

7.8 FiscalCopiarComprobante

Reimprime una copia de un comprobante emitido.

oCopia.Init(oConfig)
oCopia.SetNumeroComprobante(12345)
oCopia.Run()

8. Orquestador de documentos (FiscalOrchestra)

FiscalOrchestra es el componente de más alto nivel. Gestiona el ciclo de vida completo de un comprobante fiscal, acumulando comandos en una cola y ejecutándolos con una UI de progreso.

Inicialización

oOrch.Init('Emisión Factura B')! Título visible en la ventana de progreso
oOrch.SetConfig(oConfig)

Métodos de construcción del documento

Cliente (datos del receptor)

oOrch.Cliente(
cuit,! CUIT del cliente (string, sin guiones)
razonSocial,! Razón social o nombre
domicilio,! Domicilio completo
condIVA ! Ver FiscalCondIVA en FiscalTypes.inc)

Título (cabecera del comprobante)

oOrch.Titulo(
tipoDoc,! Ver FiscalDocType en FiscalTypes.inc (ej: Doc_FacturaB)
copias,! Cantidad de copias a imprimir
referencia ! Número de comprobante de referencia (para NC/ND))

Ítem (líneas del cuerpo)

oOrch.Item(
descripcion,! Texto de la línea
cantidad,! Cantidad (DECIMAL)
precioUnitario,! Precio unitario (DECIMAL)
ivaCondicion,! Ver FiscalIVACond (Gravado, Exento, NoGravado)
ivaAlicuota,! Alícuota de IVA (ej: 21.00)
codigoProducto ! Código interno del producto)

Pago

oOrch.Pago(
medioPago,! Ver FiscalPayment en FiscalTypes.inc
importe,! Importe del pago (DECIMAL)
descripcion ! Descripción opcional)

Percepción

oOrch.Percepcion(
tipoImpuesto,! Ver FiscalTaxType
alicuota,! Alícuota
importe ! Importe percibido)

Bonificación / Descuento

oOrch.Bonif(
descripcion,
importe,! Positivo = descuento, negativo = recargo
ivaCondicion
)

Ajuste

oOrch.Ajuste(descripcion, importe)

Cierre del comprobante

oOrch.Cierre()

Sección no fiscal (textos sin efecto fiscal)

oOrch.TituloNF(texto)! Título de sección no fiscal
oOrch.TextoNF(texto)! Línea de texto libre
oOrch.CierreNF()! Cierre de sección no fiscal

Zonas de texto (header/footer del comprobante)

oOrch.ZonaHead(texto, atributos)! Encabezado del ticket
oOrch.ZonaFoot(texto, atributos)! Pie del ticket
oOrch.ZonaDomicilioEmisor(texto)! Domicilio del emisor
oOrch.ZonaFantasia(texto)! Nombre de fantasía

Los atributos de texto se combinan con OR de bit usando las constantes de FiscalTextAttr:

! Ejemplo: texto centrado y negritaattr = FiscalAttr_Centered |: FiscalAttr_Bold
oOrch.ZonaHead('MI EMPRESA S.A.', attr)

Ejecución

oOrch.Run()! Abre ventana de progreso y ejecuta toda la cola de comandos

Run() muestra una ventana modal con:

  • Lista de comandos pendientes / ejecutados
  • Barra animada de progreso (PulseBarClass) durante reintentos
  • Botón cancelar (pregunta confirmación antes de abortar)

Ventana de progreso del orquestador

Cancelación

oOrch.Cancelar()! Cancela la operación en curso en el controlador
oOrch.AskAbort()! Pide confirmación al usuario antes de cancelar

9. Tipos y enumeraciones (FiscalTypes)

Todas las constantes están definidas en FiscalTypes.inc.

Tipos de controlador (Fiscal_Type)

Fiscal_TM2000AF ! Epson TM-2000AF
Fiscal_TM2000AFplus! Epson TM-2000AF+Fiscal_TMU220AF ! Epson TM-U220AFFiscal_ND_3 ! Genérico N/A-3Fiscal_ND_5 ! Genérico N/A-5Fiscal_LX300 ! Epson LX-300Fiscal_Hasar_441 ! Hasar 441Fiscal_Hasar_1000 ! Hasar 1000

Tipos de documento (FiscalDocType)

Doc_FacturaA  Doc_FacturaB Doc_FacturaC
Doc_NotaDeCreditoA  Doc_NotaDeCreditoB Doc_NotaDeCreditoC
Doc_NotaDeDebitoA  Doc_NotaDeDebitoB Doc_NotaDeDebitoC
Doc_ReciboA  Doc_ReciboB Doc_ReciboC
Doc_TiqueFacturaA  Doc_TiqueFacturaB Doc_TiqueFacturaC
Doc_TiqueNotaCreditoDoc_InformeDiarioDeCierre ! Cierre ZDoc_DetalleDeVentas ! Informe XDoc_Remito  Doc_Presupuesto Doc_MensajeCF
Doc_ComprobanteDonacion! ... y más de 40 tipos en total

Condición IVA del ítem (FiscalIVACond)

IVA_GravadoIVA_ExentoIVA_NoGravado

Responsabilidad IVA del emisor/receptor (FiscalCondIVA)

IVA_ResponsableInscriptoIVA_ExentoIVA_NoResponsableIVA_MonotributoIVA_ResponsableMonotributoIVA_GranContribuyenteIVA_Consumidor_Final

Medios de pago (FiscalPayment)

Pay_Efectivo  Pay_Cheque
Pay_TarjetaCredito  Pay_TarjetaDebito
Pay_TransferenciaBancaria Pay_CuentaCorriente
Pay_Vales  Pay_Otro
! ... más de 30 tipos

Tipos de impuesto adicional (FiscalTaxType)

Tax_Nacional  Tax_Provincial Tax_Municipal
Tax_Interno  Tax_IIBB Tax_PercepcionIVA

Atributos de texto (FiscalTextAttr) — flags de bit

FiscalAttr_Deleted =01H! TachadoFiscalAttr_Wide =02H! Ancho dobleFiscalAttr_Centered =04H! CentradoFiscalAttr_Bold =08H! Negrita

Estaciones de impresión (FiscalStation)

Station_TicketStation_SlipStation_Default

Zonas del comprobante (FiscalZone)

Zone_Fantasia ! Nombre de fantasíaZone_Domicilio ! Domicilio del emisorZone_Header1 ! Encabezado línea 1Zone_Header2 ! Encabezado línea 2Zone_Footer1 ! Pie línea 1Zone_Footer2 ! Pie línea 2

10. Manejo de errores (FiscalErrors)

Flags de estado (combinables con OR de bit)

FISCAL_OK =000H! Sin erroresFISCAL_ERROR =001H! Error genéricoFISCAL_PRINTER_ERROR =002H! Error físico de impresoraFISCAL_SYNTAX_ERROR =004H! Error de sintaxis de comandoFISCAL_NET_ERROR =008H! Error de red/HTTPFISCAL_BUSY =010H! Controlador ocupadoFISCAL_RESPONSE_ERROR =020H! Respuesta inesperadaFISCAL_UNKNOWN =040H! Estado desconocidoFISCAL_UNKNOWN_COMMAND =080H! Comando no reconocidoFISCAL_AUX =100H! Mensaje auxiliarFISCAL_INTERNAL =200H! Error interno del controlador

Categorías de mensajes del controlador

Los mensajes del controlador están catalogados en rangos numéricos:

RangoCategoría
101–116FISCAL_PRINTER_ERROR — Error físico de impresora
201–216FISCAL_ERROR — Error fiscal/lógico
301–307FISCAL_AUX — Mensajes auxiliares informativos
400–417FISCAL_INTERNAL — Errores internos del controlador

Consulta de descripción de error

desc = oErrors.GetErrorDesc(codigo)! Retorna descripción en español

FiscalErrors contiene un catálogo de más de 200 códigos de error clasificados en categorías: Sistema, E/S, Socket, XML, JSON, Criptografía, Imagen, POS, Auditoría, Memoria Fiscal, Aritmética, Base de Datos, Protocolo e Interfaz.


11. Logging (FiscalLog)

El sistema de logging registra todos los comandos enviados y respuestas recibidas.

Configuración

! Habilitar via variable de entorno (ZVar_GetAndSet)
ZVar_GetAndSet('Fiscal.Log',1)! 1 = activo, 0 = inactivo! O directamente via FiscalConfig:
oConfig.SetLogEnable(1)
oConfig.SetLogFilename('C:\Logs\fiscal')

Nombre del archivo de log

{ruta_base}_{serie}_{YYYY}_{MM}.log
Ejemplo: C:\Logs\fiscal_A12345678_2026_04.log

Formato de entrada

[2026-04-24 14:32:10] → {"AbrirComprobante":{...}}
[2026-04-24 14:32:11] ← {"AbrirComprobante":{"Secuencia":"12345",...}}

Uso programático (raramente necesario directamente)

oLog.Init(oConfig)
oLog.Write('Mensaje de texto plano')
oLog.Write(cstring_var)

Los comandos de FiscalCommand llaman a FiscalLog automáticamente en cada envío/respuesta.


12. Protocolo JSON

Formato de solicitud

{
"NombreComando": {
"Parametro1": "valor1",
"Parametro2": "valor2"
}
}

Formato de respuesta — Éxito

{
"NombreComando": {
"Secuencia": "12345",
"Estado": {
"Impresora": ["estado1", "estado2"],
"Fiscal": ["estadoFiscal1"]
},
"CamposEspecificos": "..."
}
}

Formato de respuesta — Controlador ocupado

{
"ControladorOcupado": {
"Secuencia": "12345",
"Estado": { ... }
}
}

Cuando el controlador responde ControladorOcupado, FiscalCommand entra en bucle de reintento automático. La frecuencia y cantidad de reintentos son configurables. Durante la espera, se invoca el callback MyNotifyClass que activa la animación de PulseBarClass.

Formato de respuesta — Error

{
"Error": {
"Identificador": "CODIGO_ERROR",
"Descripcion": "Descripción del error",
"Contexto": "Información adicional"
}
}

13. Flujo de trabajo completo

Ejemplo mínimo: Factura B

! 1. Crear y configurar el coordinador de conexión
oFiscal.SetPDF(idPuntDeVenta)
oFiscal.SetConnectionString(connStr)IF NOT oFiscal.Open()Message('Error al conectar con el controlador fiscal')RETURNEND! 2. Crear el orquestador
oOrch.Init('Emisión Factura B')! 3. Datos del receptor
oOrch.Cliente('20304050607','Juan Perez','Av. Corrientes 1234', IVA_Consumidor_Final)! 4. Tipo de comprobante
oOrch.Titulo(Doc_FacturaB,1,'')! 5. Ítems
oOrch.Item('Producto A',2,1500.00, IVA_Gravado,21.00,'001')
oOrch.Item('Producto B',1,800.50, IVA_Gravado,10.50,'002')! 6. Pago
oOrch.Pago(Pay_Efectivo,3800.50,'')! 7. Cerrar el comprobante
oOrch.Cierre()! 8. Ejecutar (muestra ventana de progreso)
oOrch.Run()

Ejemplo: Cierre Z diario

! Solo ejecutar si se confirmó con el operadorIFMessage('¿Confirma el Cierre Z?','Cierre Diario',BUTTON:YesNo)=BUTTON:Yes
oCierreZ.Init(oConfig)IF oCierreZ.Run()= FISCAL_OK
Message('Cierre Z N° '& oCierreZ.GetNroZ()&' realizado correctamente.')ELSEMessage('Error en Cierre Z: '& oCierreZ.GetLastError())ENDEND

Ejemplo: Auditoría por fecha

 oAudit.Init(oConfig)
oAudit.SetFechaDesde('20260101')
oAudit.SetFechaHasta('20260131')IF oAudit.Run()<> FISCAL_OK
Message('Error de auditoría: '& oAudit.GetLastError())END

14. Referencia de bases de datos

Tabla pdf_config

CampoTipoDescripción
id_pdfLONGIdentificador del punto de venta
ipSTRINGIP del controlador fiscal (ej: "192.168.1.50")

Tabla pdf_fiscales

CampoTipoDescripción
serieSTRINGNúmero de serie del controlador
prefijoSTRINGPrefijo del punto de venta (ej: "0001")
marcaLONG1=Epson, 2=Hasar, 9=Virtual
modeloLONGConstante Fiscal_Type (ver sección 9)
if_ncLONGFlag de notas de crédito

Consultas ejecutadas por FiscalClass

-- LoadIP()SELECT ip FROM pdf_config WHERE id_pdf = :pdf
-- LoadParams() (tras obtener serial del controlador)SELECT prefijo, marca, modelo, if_nc
FROM pdf_fiscales
WHERE serie = :serial

Versión

La constante FISCAL_VERSION (definida en FiscalTypes.inc) identifica la versión de la biblioteca.

Formato:YY.MM.DDX

ParteDescripciónEjemplo
YYAño (2 dígitos)26
MMMes (2 dígitos)04
DDDía (2 dígitos)25
XRevisión del día (letra: A, B, C…)A

Historial

VersiónCambios
26.04.25APrimera versión pública

Notas para el desarrollador

  • Nunca instanciar FiscalConfig directamente: es un singleton. Acceder siempre a través de su instancia global.
  • El Cierre Z es irreversible: validar siempre con el operador antes de ejecutarlo.
  • LibCurl debe estar en el PATH o en la carpeta del ejecutable: sin él, todos los comandos fallan con HTTP:CURL_ERROR.
  • El logging crea un archivo por mes: monitorear espacio en disco en instalaciones con alto volumen de comprobantes.
  • FiscalOrchestra.Run() es bloqueante: abre una ventana modal. Si se necesita integración en un proceso batch sin UI, ejecutar los comandos directamente vía sus clases concretas.
  • Reintentos por ControladorOcupado: el controlador puede estar procesando un trabajo anterior. FiscalCommand reintenta automáticamente; el desarrollador puede configurar el número de intentos y el delay entre ellos.

About

Hasar Fiscal Printer Driver

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - gsaracca/FiscalClass: Hasar Fiscal Printer Driver · GitHub
Skip to content

Latest commit

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

FiscalClass — Biblioteca Clarion para Controladores Fiscales

Biblioteca de clases Clarion para integración con controladores fiscales electrónicos argentinos. Gestiona la comunicación HTTP/JSON con la impresora, el ciclo de vida completo de comprobantes (facturas, notas de crédito, cierres), auditoría y logging.

Autor: Gustavo Saracca
Plataforma: Clarion (CLW/INC)
Contacto:gsaracca@gmail.comPaís: Argentina — Controladores fiscales homologados AFIP
Licencia:MIT


Índice

  1. Requisitos y dependencias
  2. Estructura de archivos
  3. Arquitectura general
  4. Configuración inicial (FiscalConfig)
  5. Inicialización de conexión (FiscalClass)
  6. Capa de transporte HTTP (FiscalHTTP)
  7. Comandos disponibles
  8. Orquestador de documentos (FiscalOrchestra)
  9. Tipos y enumeraciones (FiscalTypes)
  10. Manejo de errores (FiscalErrors)
  11. Logging (FiscalLog)
  12. Protocolo JSON
  13. Flujo de trabajo completo
  14. Referencia de bases de datos

1. Requisitos y dependencias

Bibliotecas externas requeridas

ArchivoPropósito
LibCurl.inc / LibCurl.libComunicación HTTP (POST al controlador fiscal)
cJson.inc / cJson.libSerialización/deserialización JSON
..\access\access.libUtilidades de base de datos y presentación de mensajes
..\group\group.libGestión de variables globales (ZVar_GetAndSet)

Wrapper Clarion para la biblioteca libcurl, que permite realizar peticiones HTTP/HTTPS desde código Clarion nativo. FiscalClass la utiliza a través de TCurlClass para enviar los comandos JSON al controlador fiscal mediante HTTP POST al endpoint http://<ip>/fiscal.json. Es un requisito indispensable: sin esta biblioteca, todos los comandos fallan con HTTP:CURL_ERROR.

La DLL libcurl.dll debe estar disponible en el PATH del sistema o en la carpeta del ejecutable.

Wrapper Clarion para el parser cJSON, que provee serialización y deserialización de documentos JSON. FiscalClass lo utiliza para construir los payloads de cada comando (solicitudes) y para interpretar las respuestas del controlador fiscal (éxito, error, ControladorOcupado). Sin esta biblioteca no es posible comunicarse con el controlador, ya que el protocolo completo está basado en JSON.

Variables globales requeridas (via ZVar_GetAndSet)

VariableTipoDescripción
Fiscal.LogLONG1 = logging habilitado, 0 = deshabilitado

Tabla SQL requerida: pdf_config

-- Mapea cada punto de venta (PDF) a la IP del controlador fiscal
pdf_config (
id_pdf -- Identificador del punto de venta
ip -- Dirección IP del controlador fiscal (ej: "192.168.1.50")
)

Tabla SQL requerida: pdf_fiscales

-- Mapea el número de serie fiscal a configuración del punto de venta
pdf_fiscales (
serie -- Número de serie del controlador (ej: "A12345678")
prefijo -- Prefijo del comprobante (ej: "0001")
marca -- 1=Epson, 2=Hasar, 9=Virtual
modelo -- Ver enumeración Fiscal_Type en FiscalTypes.inc
if_nc -- Flag notas de crédito
)

2. Estructura de archivos

FiscalClass/
│
├── FiscalTypes.inc ← Enumeraciones y constantes globales
│
├── FiscalConfig.clw / .inc ← Singleton de configuración global
├── FiscalLog.clw / .inc ← Subsistema de logging
├── FiscalErrors.clw / .inc ← Registro de códigos de error
├── FiscalTools.clw / .inc ← Utilidades (zonas, flags de texto)
│
├── FiscalHTTP.clw / .inc ← Capa HTTP con LibCurl
├── FiscalCommand.clw / .inc ← Clase base de comandos + lógica de reintentos
│
├── FiscalClass.clw / .inc ← Coordinador principal (conexión, inicialización)
│
│ ── Comandos específicos ──
├── FiscalInicializacion.clw / .inc ← Consulta datos del controlador
├── FiscalConsultarEstado.clw / .inc ← Estado actual del controlador
├── FiscalCancelar.clw / .inc ← Cancelar operación en curso
├── FiscalCierreX.clw / .inc ← Informe X (subtotal sin borrar)
├── FiscalCierreZ.clw / .inc ← Cierre Z (cierre diario definitivo)
├── FiscalAuditDate.clw / .inc ← Auditoría por rango de fechas
├── FiscalAuditNumber.clw / .inc ← Auditoría por rango de número Z
├── FiscalCopiarComprobante.clw / .inc← Reimpresión de comprobante
│
├── FiscalOrchestra.clw / .inc ← Orquestador de alto nivel (workflow completo)
├── FiscalMail.clw ← Envío de documentos por correo
│
└── PulseBarClass.clw / .inc ← Control visual de progreso (barra animada)

3. Arquitectura general

La biblioteca está organizada en capas bien definidas:

┌─────────────────────────────────────────────────────┐
│ FiscalOrchestra │ ← Capa de aplicación
│ (workflow, UI, cola de comandos) │
└─────────────────┬───────────────────────────────────┘
│ usa
┌─────────────────▼───────────────────────────────────┐
│ FiscalInicializacion FiscalCierreZ FiscalCierreX │ ← Comandos concretos
│ FiscalConsultarEstado FiscalCancelar FiscalAudit… │
└─────────────────┬───────────────────────────────────┘
│ heredan
┌─────────────────▼───────────────────────────────────┐
│ FiscalCommand / FiscalCommandClass │ ← Base: JSON + reintentos
└─────────────────┬───────────────────────────────────┘
│ hereda
┌─────────────────▼───────────────────────────────────┐
│ FiscalHTTP │ ← HTTP POST via LibCurl
└─────────────────────────────────────────────────────┘
Transversal a todas las capas:
FiscalConfig (singleton de configuración)
FiscalLog (logging a archivo)
FiscalErrors (catálogo de errores)

Jerarquía de herencia de clases

FiscalHTTP
└─ FiscalCommandClass
└─ FiscalCommand (wrapper con reintentos automáticos)
├─ FiscalInicializacion
├─ FiscalConsultarEstado
├─ FiscalCancelar
├─ FiscalCierreX
├─ FiscalCierreZ
├─ FiscalAuditDate
├─ FiscalAuditNumber
└─ FiscalCopiarComprobante

4. Configuración inicial (FiscalConfig)

FiscalConfig es un objeto global singleton (instancia única compartida). No debe ser instanciado manualmente; se accede a través de su instancia global.

Propiedades configurables

MétodoDescripción
SetIP(string)IP del controlador fiscal
SetSerial(string)Número de serie del controlador
SetMarca(long)Marca: 1=Epson, 2=Hasar, 9=Virtual
SetModelo(long)Modelo (ver Fiscal_Type en FiscalTypes.inc)
SetPrefijo(string)Prefijo del punto de venta (ej: "0001")
SetNC(long)Flag notas de crédito
SetIIBB(string)Número de inscripción IIBB
SetCondIVA(long)Condición frente al IVA
SetLogEnable(long)Habilitar/deshabilitar logging
SetLogFilename(string)Ruta base del archivo de log
SetMsgBox(long)Controla presentación de mensajes

Mapeo de marca a string

1 → "Epson"
2 → "Hasar"
9 → "Virtual"

Mapeo de modelo a string

Fiscal_TM2000AF → "TM2000AF"
Fiscal_TM2000AFplus→ "TM2000AF+"
Fiscal_TMU220AF → "TMU220AF"
Fiscal_ND_3 → "N/A-3"
Fiscal_ND_5 → "N/A-5"
Fiscal_LX300 → "LX-300"
Fiscal_Hasar_441 → "441"
Fiscal_Hasar_1000 → "1000"

5. Inicialización de conexión (FiscalClass)

FiscalClass coordina la inicialización completa leyendo la configuración desde la base de datos.

Métodos principales

MétodoDescripción
SetPDF(long)Define el ID del punto de venta
SetConnectionString(string)Cadena de conexión SQL
Open()Ejecuta el flujo completo de inicialización
LoadIP()Lee la IP desde pdf_config
LoadFiscal()Consulta el controlador y carga serial/prefijo
LoadParams()Lee marca y modelo desde pdf_fiscales

Flujo de Open()

Open()
├─ LoadIP() → Lee ip de pdf_config WHERE id_pdf = @pdf
├─ LoadFiscal() → Ejecuta FiscalInicializacion, guarda serial/prefijo
└─ LoadParams() → Lee marca/modelo de pdf_fiscales WHERE serie = @serial

Atributos disponibles tras Open()

oFiscal.GetPDF()! ID del punto de venta
oFiscal.GetPrefijo()! Prefijo cargado desde controlador
oFiscal.GetConfigPrefijo()! Prefijo cargado desde base de datos

6. Capa de transporte HTTP (FiscalHTTP)

FiscalHTTP encapsula la comunicación HTTP POST usando TCurlClass (LibCurl).

Endpoint

POST http://<ip>/fiscal.json
Content-Type: application/json

Atributos de resultado

AtributoDescripción
HTTPCodeCódigo de respuesta HTTP
HTTPMessageCuerpo de la respuesta (JSON)
HTTPErrorCódigo de error interno

Códigos de error HTTP internos

HTTP:CURL_OK =0! ExitosoHTTP:CURL_ERROR =1! Error de LibCurlHTTP:NET_ERROR =2! Respuesta HTTP 3xx-5xx

7. Comandos disponibles

Todos los comandos heredan de FiscalCommand e implementan el método Run().

7.1 FiscalInicializacion

Consulta los datos de identificación del controlador fiscal.

Respuesta relevante:

  • CUIT del emisor
  • Razón social
  • Número de serie
  • Prefijo del punto de venta
oInit.Init(oConfig)IF oInit.Run()= FISCAL_OK
serial = oInit.GetSerial()
prefijo = oInit.GetPrefijo()
cuit = oInit.GetCUIT()END

7.2 FiscalConsultarEstado

Obtiene el estado actual del controlador y el último comprobante emitido.

oEstado.Init(oConfig)IF oEstado.Run()= FISCAL_OK
estado = oEstado.GetEstado()
ultimo = oEstado.GetUltimoComprobante()END

7.3 FiscalCancelar

Cancela la operación en curso en el controlador.

oCancel.Init(oConfig)
oCancel.Run()

7.4 FiscalCierreX — Informe X

Emite un informe de subtotales sin borrar la memoria fiscal. Equivale a un "corte X" en terminología fiscal.

oCierreX.Init(oConfig)IF oCierreX.Run()= FISCAL_OK
! Informe impreso en el controladorEND

7.5 FiscalCierreZ — Cierre diario

Emite el cierre diario definitivo. Borra los acumuladores y avanza el contador Z.

oCierreZ.Init(oConfig)IF oCierreZ.Run()= FISCAL_OK
nroZ = oCierreZ.GetNroZ()
totalZ = oCierreZ.GetTotal()END

Importante: Esta operación es irreversible. El controlador fiscal homologado no permite anular un cierre Z.

7.6 FiscalAuditDate — Auditoría por fecha

Imprime el informe de auditoría para un rango de fechas.

oAudit.Init(oConfig)
oAudit.SetFechaDesde('20260101')
oAudit.SetFechaHasta('20260131')
oAudit.Run()

7.7 FiscalAuditNumber — Auditoría por número Z

Imprime el informe de auditoría para un rango de números de cierre Z.

oAuditN.Init(oConfig)
oAuditN.SetZDesde(100)
oAuditN.SetZHasta(150)
oAuditN.Run()

7.8 FiscalCopiarComprobante

Reimprime una copia de un comprobante emitido.

oCopia.Init(oConfig)
oCopia.SetNumeroComprobante(12345)
oCopia.Run()

8. Orquestador de documentos (FiscalOrchestra)

FiscalOrchestra es el componente de más alto nivel. Gestiona el ciclo de vida completo de un comprobante fiscal, acumulando comandos en una cola y ejecutándolos con una UI de progreso.

Inicialización

oOrch.Init('Emisión Factura B')! Título visible en la ventana de progreso
oOrch.SetConfig(oConfig)

Métodos de construcción del documento

Cliente (datos del receptor)

oOrch.Cliente(
cuit,! CUIT del cliente (string, sin guiones)
razonSocial,! Razón social o nombre
domicilio,! Domicilio completo
condIVA ! Ver FiscalCondIVA en FiscalTypes.inc)

Título (cabecera del comprobante)

oOrch.Titulo(
tipoDoc,! Ver FiscalDocType en FiscalTypes.inc (ej: Doc_FacturaB)
copias,! Cantidad de copias a imprimir
referencia ! Número de comprobante de referencia (para NC/ND))

Ítem (líneas del cuerpo)

oOrch.Item(
descripcion,! Texto de la línea
cantidad,! Cantidad (DECIMAL)
precioUnitario,! Precio unitario (DECIMAL)
ivaCondicion,! Ver FiscalIVACond (Gravado, Exento, NoGravado)
ivaAlicuota,! Alícuota de IVA (ej: 21.00)
codigoProducto ! Código interno del producto)

Pago

oOrch.Pago(
medioPago,! Ver FiscalPayment en FiscalTypes.inc
importe,! Importe del pago (DECIMAL)
descripcion ! Descripción opcional)

Percepción

oOrch.Percepcion(
tipoImpuesto,! Ver FiscalTaxType
alicuota,! Alícuota
importe ! Importe percibido)

Bonificación / Descuento

oOrch.Bonif(
descripcion,
importe,! Positivo = descuento, negativo = recargo
ivaCondicion
)

Ajuste

oOrch.Ajuste(descripcion, importe)

Cierre del comprobante

oOrch.Cierre()

Sección no fiscal (textos sin efecto fiscal)

oOrch.TituloNF(texto)! Título de sección no fiscal
oOrch.TextoNF(texto)! Línea de texto libre
oOrch.CierreNF()! Cierre de sección no fiscal

Zonas de texto (header/footer del comprobante)

oOrch.ZonaHead(texto, atributos)! Encabezado del ticket
oOrch.ZonaFoot(texto, atributos)! Pie del ticket
oOrch.ZonaDomicilioEmisor(texto)! Domicilio del emisor
oOrch.ZonaFantasia(texto)! Nombre de fantasía

Los atributos de texto se combinan con OR de bit usando las constantes de FiscalTextAttr:

! Ejemplo: texto centrado y negritaattr = FiscalAttr_Centered |: FiscalAttr_Bold
oOrch.ZonaHead('MI EMPRESA S.A.', attr)

Ejecución

oOrch.Run()! Abre ventana de progreso y ejecuta toda la cola de comandos

Run() muestra una ventana modal con:

  • Lista de comandos pendientes / ejecutados
  • Barra animada de progreso (PulseBarClass) durante reintentos
  • Botón cancelar (pregunta confirmación antes de abortar)

Ventana de progreso del orquestador

Cancelación

oOrch.Cancelar()! Cancela la operación en curso en el controlador
oOrch.AskAbort()! Pide confirmación al usuario antes de cancelar

9. Tipos y enumeraciones (FiscalTypes)

Todas las constantes están definidas en FiscalTypes.inc.

Tipos de controlador (Fiscal_Type)

Fiscal_TM2000AF ! Epson TM-2000AF
Fiscal_TM2000AFplus! Epson TM-2000AF+Fiscal_TMU220AF ! Epson TM-U220AFFiscal_ND_3 ! Genérico N/A-3Fiscal_ND_5 ! Genérico N/A-5Fiscal_LX300 ! Epson LX-300Fiscal_Hasar_441 ! Hasar 441Fiscal_Hasar_1000 ! Hasar 1000

Tipos de documento (FiscalDocType)

Doc_FacturaA  Doc_FacturaB Doc_FacturaC
Doc_NotaDeCreditoA  Doc_NotaDeCreditoB Doc_NotaDeCreditoC
Doc_NotaDeDebitoA  Doc_NotaDeDebitoB Doc_NotaDeDebitoC
Doc_ReciboA  Doc_ReciboB Doc_ReciboC
Doc_TiqueFacturaA  Doc_TiqueFacturaB Doc_TiqueFacturaC
Doc_TiqueNotaCreditoDoc_InformeDiarioDeCierre ! Cierre ZDoc_DetalleDeVentas ! Informe XDoc_Remito  Doc_Presupuesto Doc_MensajeCF
Doc_ComprobanteDonacion! ... y más de 40 tipos en total

Condición IVA del ítem (FiscalIVACond)

IVA_GravadoIVA_ExentoIVA_NoGravado

Responsabilidad IVA del emisor/receptor (FiscalCondIVA)

IVA_ResponsableInscriptoIVA_ExentoIVA_NoResponsableIVA_MonotributoIVA_ResponsableMonotributoIVA_GranContribuyenteIVA_Consumidor_Final

Medios de pago (FiscalPayment)

Pay_Efectivo  Pay_Cheque
Pay_TarjetaCredito  Pay_TarjetaDebito
Pay_TransferenciaBancaria Pay_CuentaCorriente
Pay_Vales  Pay_Otro
! ... más de 30 tipos

Tipos de impuesto adicional (FiscalTaxType)

Tax_Nacional  Tax_Provincial Tax_Municipal
Tax_Interno  Tax_IIBB Tax_PercepcionIVA

Atributos de texto (FiscalTextAttr) — flags de bit

FiscalAttr_Deleted =01H! TachadoFiscalAttr_Wide =02H! Ancho dobleFiscalAttr_Centered =04H! CentradoFiscalAttr_Bold =08H! Negrita

Estaciones de impresión (FiscalStation)

Station_TicketStation_SlipStation_Default

Zonas del comprobante (FiscalZone)

Zone_Fantasia ! Nombre de fantasíaZone_Domicilio ! Domicilio del emisorZone_Header1 ! Encabezado línea 1Zone_Header2 ! Encabezado línea 2Zone_Footer1 ! Pie línea 1Zone_Footer2 ! Pie línea 2

10. Manejo de errores (FiscalErrors)

Flags de estado (combinables con OR de bit)

FISCAL_OK =000H! Sin erroresFISCAL_ERROR =001H! Error genéricoFISCAL_PRINTER_ERROR =002H! Error físico de impresoraFISCAL_SYNTAX_ERROR =004H! Error de sintaxis de comandoFISCAL_NET_ERROR =008H! Error de red/HTTPFISCAL_BUSY =010H! Controlador ocupadoFISCAL_RESPONSE_ERROR =020H! Respuesta inesperadaFISCAL_UNKNOWN =040H! Estado desconocidoFISCAL_UNKNOWN_COMMAND =080H! Comando no reconocidoFISCAL_AUX =100H! Mensaje auxiliarFISCAL_INTERNAL =200H! Error interno del controlador

Categorías de mensajes del controlador

Los mensajes del controlador están catalogados en rangos numéricos:

RangoCategoría
101–116FISCAL_PRINTER_ERROR — Error físico de impresora
201–216FISCAL_ERROR — Error fiscal/lógico
301–307FISCAL_AUX — Mensajes auxiliares informativos
400–417FISCAL_INTERNAL — Errores internos del controlador

Consulta de descripción de error

desc = oErrors.GetErrorDesc(codigo)! Retorna descripción en español

FiscalErrors contiene un catálogo de más de 200 códigos de error clasificados en categorías: Sistema, E/S, Socket, XML, JSON, Criptografía, Imagen, POS, Auditoría, Memoria Fiscal, Aritmética, Base de Datos, Protocolo e Interfaz.


11. Logging (FiscalLog)

El sistema de logging registra todos los comandos enviados y respuestas recibidas.

Configuración

! Habilitar via variable de entorno (ZVar_GetAndSet)
ZVar_GetAndSet('Fiscal.Log',1)! 1 = activo, 0 = inactivo! O directamente via FiscalConfig:
oConfig.SetLogEnable(1)
oConfig.SetLogFilename('C:\Logs\fiscal')

Nombre del archivo de log

{ruta_base}_{serie}_{YYYY}_{MM}.log
Ejemplo: C:\Logs\fiscal_A12345678_2026_04.log

Formato de entrada

[2026-04-24 14:32:10] → {"AbrirComprobante":{...}}
[2026-04-24 14:32:11] ← {"AbrirComprobante":{"Secuencia":"12345",...}}

Uso programático (raramente necesario directamente)

oLog.Init(oConfig)
oLog.Write('Mensaje de texto plano')
oLog.Write(cstring_var)

Los comandos de FiscalCommand llaman a FiscalLog automáticamente en cada envío/respuesta.


12. Protocolo JSON

Formato de solicitud

{
"NombreComando": {
"Parametro1": "valor1",
"Parametro2": "valor2"
}
}

Formato de respuesta — Éxito

{
"NombreComando": {
"Secuencia": "12345",
"Estado": {
"Impresora": ["estado1", "estado2"],
"Fiscal": ["estadoFiscal1"]
},
"CamposEspecificos": "..."
}
}

Formato de respuesta — Controlador ocupado

{
"ControladorOcupado": {
"Secuencia": "12345",
"Estado": { ... }
}
}

Cuando el controlador responde ControladorOcupado, FiscalCommand entra en bucle de reintento automático. La frecuencia y cantidad de reintentos son configurables. Durante la espera, se invoca el callback MyNotifyClass que activa la animación de PulseBarClass.

Formato de respuesta — Error

{
"Error": {
"Identificador": "CODIGO_ERROR",
"Descripcion": "Descripción del error",
"Contexto": "Información adicional"
}
}

13. Flujo de trabajo completo

Ejemplo mínimo: Factura B

! 1. Crear y configurar el coordinador de conexión
oFiscal.SetPDF(idPuntDeVenta)
oFiscal.SetConnectionString(connStr)IF NOT oFiscal.Open()Message('Error al conectar con el controlador fiscal')RETURNEND! 2. Crear el orquestador
oOrch.Init('Emisión Factura B')! 3. Datos del receptor
oOrch.Cliente('20304050607','Juan Perez','Av. Corrientes 1234', IVA_Consumidor_Final)! 4. Tipo de comprobante
oOrch.Titulo(Doc_FacturaB,1,'')! 5. Ítems
oOrch.Item('Producto A',2,1500.00, IVA_Gravado,21.00,'001')
oOrch.Item('Producto B',1,800.50, IVA_Gravado,10.50,'002')! 6. Pago
oOrch.Pago(Pay_Efectivo,3800.50,'')! 7. Cerrar el comprobante
oOrch.Cierre()! 8. Ejecutar (muestra ventana de progreso)
oOrch.Run()

Ejemplo: Cierre Z diario

! Solo ejecutar si se confirmó con el operadorIFMessage('¿Confirma el Cierre Z?','Cierre Diario',BUTTON:YesNo)=BUTTON:Yes
oCierreZ.Init(oConfig)IF oCierreZ.Run()= FISCAL_OK
Message('Cierre Z N° '& oCierreZ.GetNroZ()&' realizado correctamente.')ELSEMessage('Error en Cierre Z: '& oCierreZ.GetLastError())ENDEND

Ejemplo: Auditoría por fecha

 oAudit.Init(oConfig)
oAudit.SetFechaDesde('20260101')
oAudit.SetFechaHasta('20260131')IF oAudit.Run()<> FISCAL_OK
Message('Error de auditoría: '& oAudit.GetLastError())END

14. Referencia de bases de datos

Tabla pdf_config

CampoTipoDescripción
id_pdfLONGIdentificador del punto de venta
ipSTRINGIP del controlador fiscal (ej: "192.168.1.50")

Tabla pdf_fiscales

CampoTipoDescripción
serieSTRINGNúmero de serie del controlador
prefijoSTRINGPrefijo del punto de venta (ej: "0001")
marcaLONG1=Epson, 2=Hasar, 9=Virtual
modeloLONGConstante Fiscal_Type (ver sección 9)
if_ncLONGFlag de notas de crédito

Consultas ejecutadas por FiscalClass

-- LoadIP()SELECT ip FROM pdf_config WHERE id_pdf = :pdf
-- LoadParams() (tras obtener serial del controlador)SELECT prefijo, marca, modelo, if_nc
FROM pdf_fiscales
WHERE serie = :serial

Versión

La constante FISCAL_VERSION (definida en FiscalTypes.inc) identifica la versión de la biblioteca.

Formato:YY.MM.DDX

ParteDescripciónEjemplo
YYAño (2 dígitos)26
MMMes (2 dígitos)04
DDDía (2 dígitos)25
XRevisión del día (letra: A, B, C…)A

Historial

VersiónCambios
26.04.25APrimera versión pública

Notas para el desarrollador

  • Nunca instanciar FiscalConfig directamente: es un singleton. Acceder siempre a través de su instancia global.
  • El Cierre Z es irreversible: validar siempre con el operador antes de ejecutarlo.
  • LibCurl debe estar en el PATH o en la carpeta del ejecutable: sin él, todos los comandos fallan con HTTP:CURL_ERROR.
  • El logging crea un archivo por mes: monitorear espacio en disco en instalaciones con alto volumen de comprobantes.
  • FiscalOrchestra.Run() es bloqueante: abre una ventana modal. Si se necesita integración en un proceso batch sin UI, ejecutar los comandos directamente vía sus clases concretas.
  • Reintentos por ControladorOcupado: el controlador puede estar procesando un trabajo anterior. FiscalCommand reintenta automáticamente; el desarrollador puede configurar el número de intentos y el delay entre ellos.

About

Hasar Fiscal Printer Driver

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - gsaracca/FiscalClass: Hasar Fiscal Printer Driver · GitHub
Skip to content

Latest commit

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

FiscalClass — Biblioteca Clarion para Controladores Fiscales

Biblioteca de clases Clarion para integración con controladores fiscales electrónicos argentinos. Gestiona la comunicación HTTP/JSON con la impresora, el ciclo de vida completo de comprobantes (facturas, notas de crédito, cierres), auditoría y logging.

Autor: Gustavo Saracca
Plataforma: Clarion (CLW/INC)
Contacto:gsaracca@gmail.comPaís: Argentina — Controladores fiscales homologados AFIP
Licencia:MIT


Índice

  1. Requisitos y dependencias
  2. Estructura de archivos
  3. Arquitectura general
  4. Configuración inicial (FiscalConfig)
  5. Inicialización de conexión (FiscalClass)
  6. Capa de transporte HTTP (FiscalHTTP)
  7. Comandos disponibles
  8. Orquestador de documentos (FiscalOrchestra)
  9. Tipos y enumeraciones (FiscalTypes)
  10. Manejo de errores (FiscalErrors)
  11. Logging (FiscalLog)
  12. Protocolo JSON
  13. Flujo de trabajo completo
  14. Referencia de bases de datos

1. Requisitos y dependencias

Bibliotecas externas requeridas

ArchivoPropósito
LibCurl.inc / LibCurl.libComunicación HTTP (POST al controlador fiscal)
cJson.inc / cJson.libSerialización/deserialización JSON
..\access\access.libUtilidades de base de datos y presentación de mensajes
..\group\group.libGestión de variables globales (ZVar_GetAndSet)

Wrapper Clarion para la biblioteca libcurl, que permite realizar peticiones HTTP/HTTPS desde código Clarion nativo. FiscalClass la utiliza a través de TCurlClass para enviar los comandos JSON al controlador fiscal mediante HTTP POST al endpoint http://<ip>/fiscal.json. Es un requisito indispensable: sin esta biblioteca, todos los comandos fallan con HTTP:CURL_ERROR.

La DLL libcurl.dll debe estar disponible en el PATH del sistema o en la carpeta del ejecutable.

Wrapper Clarion para el parser cJSON, que provee serialización y deserialización de documentos JSON. FiscalClass lo utiliza para construir los payloads de cada comando (solicitudes) y para interpretar las respuestas del controlador fiscal (éxito, error, ControladorOcupado). Sin esta biblioteca no es posible comunicarse con el controlador, ya que el protocolo completo está basado en JSON.

Variables globales requeridas (via ZVar_GetAndSet)

VariableTipoDescripción
Fiscal.LogLONG1 = logging habilitado, 0 = deshabilitado

Tabla SQL requerida: pdf_config

-- Mapea cada punto de venta (PDF) a la IP del controlador fiscal
pdf_config (
id_pdf -- Identificador del punto de venta
ip -- Dirección IP del controlador fiscal (ej: "192.168.1.50")
)

Tabla SQL requerida: pdf_fiscales

-- Mapea el número de serie fiscal a configuración del punto de venta
pdf_fiscales (
serie -- Número de serie del controlador (ej: "A12345678")
prefijo -- Prefijo del comprobante (ej: "0001")
marca -- 1=Epson, 2=Hasar, 9=Virtual
modelo -- Ver enumeración Fiscal_Type en FiscalTypes.inc
if_nc -- Flag notas de crédito
)

2. Estructura de archivos

FiscalClass/
│
├── FiscalTypes.inc ← Enumeraciones y constantes globales
│
├── FiscalConfig.clw / .inc ← Singleton de configuración global
├── FiscalLog.clw / .inc ← Subsistema de logging
├── FiscalErrors.clw / .inc ← Registro de códigos de error
├── FiscalTools.clw / .inc ← Utilidades (zonas, flags de texto)
│
├── FiscalHTTP.clw / .inc ← Capa HTTP con LibCurl
├── FiscalCommand.clw / .inc ← Clase base de comandos + lógica de reintentos
│
├── FiscalClass.clw / .inc ← Coordinador principal (conexión, inicialización)
│
│ ── Comandos específicos ──
├── FiscalInicializacion.clw / .inc ← Consulta datos del controlador
├── FiscalConsultarEstado.clw / .inc ← Estado actual del controlador
├── FiscalCancelar.clw / .inc ← Cancelar operación en curso
├── FiscalCierreX.clw / .inc ← Informe X (subtotal sin borrar)
├── FiscalCierreZ.clw / .inc ← Cierre Z (cierre diario definitivo)
├── FiscalAuditDate.clw / .inc ← Auditoría por rango de fechas
├── FiscalAuditNumber.clw / .inc ← Auditoría por rango de número Z
├── FiscalCopiarComprobante.clw / .inc← Reimpresión de comprobante
│
├── FiscalOrchestra.clw / .inc ← Orquestador de alto nivel (workflow completo)
├── FiscalMail.clw ← Envío de documentos por correo
│
└── PulseBarClass.clw / .inc ← Control visual de progreso (barra animada)

3. Arquitectura general

La biblioteca está organizada en capas bien definidas:

┌─────────────────────────────────────────────────────┐
│ FiscalOrchestra │ ← Capa de aplicación
│ (workflow, UI, cola de comandos) │
└─────────────────┬───────────────────────────────────┘
│ usa
┌─────────────────▼───────────────────────────────────┐
│ FiscalInicializacion FiscalCierreZ FiscalCierreX │ ← Comandos concretos
│ FiscalConsultarEstado FiscalCancelar FiscalAudit… │
└─────────────────┬───────────────────────────────────┘
│ heredan
┌─────────────────▼───────────────────────────────────┐
│ FiscalCommand / FiscalCommandClass │ ← Base: JSON + reintentos
└─────────────────┬───────────────────────────────────┘
│ hereda
┌─────────────────▼───────────────────────────────────┐
│ FiscalHTTP │ ← HTTP POST via LibCurl
└─────────────────────────────────────────────────────┘
Transversal a todas las capas:
FiscalConfig (singleton de configuración)
FiscalLog (logging a archivo)
FiscalErrors (catálogo de errores)

Jerarquía de herencia de clases

FiscalHTTP
└─ FiscalCommandClass
└─ FiscalCommand (wrapper con reintentos automáticos)
├─ FiscalInicializacion
├─ FiscalConsultarEstado
├─ FiscalCancelar
├─ FiscalCierreX
├─ FiscalCierreZ
├─ FiscalAuditDate
├─ FiscalAuditNumber
└─ FiscalCopiarComprobante

4. Configuración inicial (FiscalConfig)

FiscalConfig es un objeto global singleton (instancia única compartida). No debe ser instanciado manualmente; se accede a través de su instancia global.

Propiedades configurables

MétodoDescripción
SetIP(string)IP del controlador fiscal
SetSerial(string)Número de serie del controlador
SetMarca(long)Marca: 1=Epson, 2=Hasar, 9=Virtual
SetModelo(long)Modelo (ver Fiscal_Type en FiscalTypes.inc)
SetPrefijo(string)Prefijo del punto de venta (ej: "0001")
SetNC(long)Flag notas de crédito
SetIIBB(string)Número de inscripción IIBB
SetCondIVA(long)Condición frente al IVA
SetLogEnable(long)Habilitar/deshabilitar logging
SetLogFilename(string)Ruta base del archivo de log
SetMsgBox(long)Controla presentación de mensajes

Mapeo de marca a string

1 → "Epson"
2 → "Hasar"
9 → "Virtual"

Mapeo de modelo a string

Fiscal_TM2000AF → "TM2000AF"
Fiscal_TM2000AFplus→ "TM2000AF+"
Fiscal_TMU220AF → "TMU220AF"
Fiscal_ND_3 → "N/A-3"
Fiscal_ND_5 → "N/A-5"
Fiscal_LX300 → "LX-300"
Fiscal_Hasar_441 → "441"
Fiscal_Hasar_1000 → "1000"

5. Inicialización de conexión (FiscalClass)

FiscalClass coordina la inicialización completa leyendo la configuración desde la base de datos.

Métodos principales

MétodoDescripción
SetPDF(long)Define el ID del punto de venta
SetConnectionString(string)Cadena de conexión SQL
Open()Ejecuta el flujo completo de inicialización
LoadIP()Lee la IP desde pdf_config
LoadFiscal()Consulta el controlador y carga serial/prefijo
LoadParams()Lee marca y modelo desde pdf_fiscales

Flujo de Open()

Open()
├─ LoadIP() → Lee ip de pdf_config WHERE id_pdf = @pdf
├─ LoadFiscal() → Ejecuta FiscalInicializacion, guarda serial/prefijo
└─ LoadParams() → Lee marca/modelo de pdf_fiscales WHERE serie = @serial

Atributos disponibles tras Open()

oFiscal.GetPDF()! ID del punto de venta
oFiscal.GetPrefijo()! Prefijo cargado desde controlador
oFiscal.GetConfigPrefijo()! Prefijo cargado desde base de datos

6. Capa de transporte HTTP (FiscalHTTP)

FiscalHTTP encapsula la comunicación HTTP POST usando TCurlClass (LibCurl).

Endpoint

POST http://<ip>/fiscal.json
Content-Type: application/json

Atributos de resultado

AtributoDescripción
HTTPCodeCódigo de respuesta HTTP
HTTPMessageCuerpo de la respuesta (JSON)
HTTPErrorCódigo de error interno

Códigos de error HTTP internos

HTTP:CURL_OK =0! ExitosoHTTP:CURL_ERROR =1! Error de LibCurlHTTP:NET_ERROR =2! Respuesta HTTP 3xx-5xx

7. Comandos disponibles

Todos los comandos heredan de FiscalCommand e implementan el método Run().

7.1 FiscalInicializacion

Consulta los datos de identificación del controlador fiscal.

Respuesta relevante:

  • CUIT del emisor
  • Razón social
  • Número de serie
  • Prefijo del punto de venta
oInit.Init(oConfig)IF oInit.Run()= FISCAL_OK
serial = oInit.GetSerial()
prefijo = oInit.GetPrefijo()
cuit = oInit.GetCUIT()END

7.2 FiscalConsultarEstado

Obtiene el estado actual del controlador y el último comprobante emitido.

oEstado.Init(oConfig)IF oEstado.Run()= FISCAL_OK
estado = oEstado.GetEstado()
ultimo = oEstado.GetUltimoComprobante()END

7.3 FiscalCancelar

Cancela la operación en curso en el controlador.

oCancel.Init(oConfig)
oCancel.Run()

7.4 FiscalCierreX — Informe X

Emite un informe de subtotales sin borrar la memoria fiscal. Equivale a un "corte X" en terminología fiscal.

oCierreX.Init(oConfig)IF oCierreX.Run()= FISCAL_OK
! Informe impreso en el controladorEND

7.5 FiscalCierreZ — Cierre diario

Emite el cierre diario definitivo. Borra los acumuladores y avanza el contador Z.

oCierreZ.Init(oConfig)IF oCierreZ.Run()= FISCAL_OK
nroZ = oCierreZ.GetNroZ()
totalZ = oCierreZ.GetTotal()END

Importante: Esta operación es irreversible. El controlador fiscal homologado no permite anular un cierre Z.

7.6 FiscalAuditDate — Auditoría por fecha

Imprime el informe de auditoría para un rango de fechas.

oAudit.Init(oConfig)
oAudit.SetFechaDesde('20260101')
oAudit.SetFechaHasta('20260131')
oAudit.Run()

7.7 FiscalAuditNumber — Auditoría por número Z

Imprime el informe de auditoría para un rango de números de cierre Z.

oAuditN.Init(oConfig)
oAuditN.SetZDesde(100)
oAuditN.SetZHasta(150)
oAuditN.Run()

7.8 FiscalCopiarComprobante

Reimprime una copia de un comprobante emitido.

oCopia.Init(oConfig)
oCopia.SetNumeroComprobante(12345)
oCopia.Run()

8. Orquestador de documentos (FiscalOrchestra)

FiscalOrchestra es el componente de más alto nivel. Gestiona el ciclo de vida completo de un comprobante fiscal, acumulando comandos en una cola y ejecutándolos con una UI de progreso.

Inicialización

oOrch.Init('Emisión Factura B')! Título visible en la ventana de progreso
oOrch.SetConfig(oConfig)

Métodos de construcción del documento

Cliente (datos del receptor)

oOrch.Cliente(
cuit,! CUIT del cliente (string, sin guiones)
razonSocial,! Razón social o nombre
domicilio,! Domicilio completo
condIVA ! Ver FiscalCondIVA en FiscalTypes.inc)

Título (cabecera del comprobante)

oOrch.Titulo(
tipoDoc,! Ver FiscalDocType en FiscalTypes.inc (ej: Doc_FacturaB)
copias,! Cantidad de copias a imprimir
referencia ! Número de comprobante de referencia (para NC/ND))

Ítem (líneas del cuerpo)

oOrch.Item(
descripcion,! Texto de la línea
cantidad,! Cantidad (DECIMAL)
precioUnitario,! Precio unitario (DECIMAL)
ivaCondicion,! Ver FiscalIVACond (Gravado, Exento, NoGravado)
ivaAlicuota,! Alícuota de IVA (ej: 21.00)
codigoProducto ! Código interno del producto)

Pago

oOrch.Pago(
medioPago,! Ver FiscalPayment en FiscalTypes.inc
importe,! Importe del pago (DECIMAL)
descripcion ! Descripción opcional)

Percepción

oOrch.Percepcion(
tipoImpuesto,! Ver FiscalTaxType
alicuota,! Alícuota
importe ! Importe percibido)

Bonificación / Descuento

oOrch.Bonif(
descripcion,
importe,! Positivo = descuento, negativo = recargo
ivaCondicion
)

Ajuste

oOrch.Ajuste(descripcion, importe)

Cierre del comprobante

oOrch.Cierre()

Sección no fiscal (textos sin efecto fiscal)

oOrch.TituloNF(texto)! Título de sección no fiscal
oOrch.TextoNF(texto)! Línea de texto libre
oOrch.CierreNF()! Cierre de sección no fiscal

Zonas de texto (header/footer del comprobante)

oOrch.ZonaHead(texto, atributos)! Encabezado del ticket
oOrch.ZonaFoot(texto, atributos)! Pie del ticket
oOrch.ZonaDomicilioEmisor(texto)! Domicilio del emisor
oOrch.ZonaFantasia(texto)! Nombre de fantasía

Los atributos de texto se combinan con OR de bit usando las constantes de FiscalTextAttr:

! Ejemplo: texto centrado y negritaattr = FiscalAttr_Centered |: FiscalAttr_Bold
oOrch.ZonaHead('MI EMPRESA S.A.', attr)

Ejecución

oOrch.Run()! Abre ventana de progreso y ejecuta toda la cola de comandos

Run() muestra una ventana modal con:

  • Lista de comandos pendientes / ejecutados
  • Barra animada de progreso (PulseBarClass) durante reintentos
  • Botón cancelar (pregunta confirmación antes de abortar)

Ventana de progreso del orquestador

Cancelación

oOrch.Cancelar()! Cancela la operación en curso en el controlador
oOrch.AskAbort()! Pide confirmación al usuario antes de cancelar

9. Tipos y enumeraciones (FiscalTypes)

Todas las constantes están definidas en FiscalTypes.inc.

Tipos de controlador (Fiscal_Type)

Fiscal_TM2000AF ! Epson TM-2000AF
Fiscal_TM2000AFplus! Epson TM-2000AF+Fiscal_TMU220AF ! Epson TM-U220AFFiscal_ND_3 ! Genérico N/A-3Fiscal_ND_5 ! Genérico N/A-5Fiscal_LX300 ! Epson LX-300Fiscal_Hasar_441 ! Hasar 441Fiscal_Hasar_1000 ! Hasar 1000

Tipos de documento (FiscalDocType)

Doc_FacturaA  Doc_FacturaB Doc_FacturaC
Doc_NotaDeCreditoA  Doc_NotaDeCreditoB Doc_NotaDeCreditoC
Doc_NotaDeDebitoA  Doc_NotaDeDebitoB Doc_NotaDeDebitoC
Doc_ReciboA  Doc_ReciboB Doc_ReciboC
Doc_TiqueFacturaA  Doc_TiqueFacturaB Doc_TiqueFacturaC
Doc_TiqueNotaCreditoDoc_InformeDiarioDeCierre ! Cierre ZDoc_DetalleDeVentas ! Informe XDoc_Remito  Doc_Presupuesto Doc_MensajeCF
Doc_ComprobanteDonacion! ... y más de 40 tipos en total

Condición IVA del ítem (FiscalIVACond)

IVA_GravadoIVA_ExentoIVA_NoGravado

Responsabilidad IVA del emisor/receptor (FiscalCondIVA)

IVA_ResponsableInscriptoIVA_ExentoIVA_NoResponsableIVA_MonotributoIVA_ResponsableMonotributoIVA_GranContribuyenteIVA_Consumidor_Final

Medios de pago (FiscalPayment)

Pay_Efectivo  Pay_Cheque
Pay_TarjetaCredito  Pay_TarjetaDebito
Pay_TransferenciaBancaria Pay_CuentaCorriente
Pay_Vales  Pay_Otro
! ... más de 30 tipos

Tipos de impuesto adicional (FiscalTaxType)

Tax_Nacional  Tax_Provincial Tax_Municipal
Tax_Interno  Tax_IIBB Tax_PercepcionIVA

Atributos de texto (FiscalTextAttr) — flags de bit

FiscalAttr_Deleted =01H! TachadoFiscalAttr_Wide =02H! Ancho dobleFiscalAttr_Centered =04H! CentradoFiscalAttr_Bold =08H! Negrita

Estaciones de impresión (FiscalStation)

Station_TicketStation_SlipStation_Default

Zonas del comprobante (FiscalZone)

Zone_Fantasia ! Nombre de fantasíaZone_Domicilio ! Domicilio del emisorZone_Header1 ! Encabezado línea 1Zone_Header2 ! Encabezado línea 2Zone_Footer1 ! Pie línea 1Zone_Footer2 ! Pie línea 2

10. Manejo de errores (FiscalErrors)

Flags de estado (combinables con OR de bit)

FISCAL_OK =000H! Sin erroresFISCAL_ERROR =001H! Error genéricoFISCAL_PRINTER_ERROR =002H! Error físico de impresoraFISCAL_SYNTAX_ERROR =004H! Error de sintaxis de comandoFISCAL_NET_ERROR =008H! Error de red/HTTPFISCAL_BUSY =010H! Controlador ocupadoFISCAL_RESPONSE_ERROR =020H! Respuesta inesperadaFISCAL_UNKNOWN =040H! Estado desconocidoFISCAL_UNKNOWN_COMMAND =080H! Comando no reconocidoFISCAL_AUX =100H! Mensaje auxiliarFISCAL_INTERNAL =200H! Error interno del controlador

Categorías de mensajes del controlador

Los mensajes del controlador están catalogados en rangos numéricos:

RangoCategoría
101–116FISCAL_PRINTER_ERROR — Error físico de impresora
201–216FISCAL_ERROR — Error fiscal/lógico
301–307FISCAL_AUX — Mensajes auxiliares informativos
400–417FISCAL_INTERNAL — Errores internos del controlador

Consulta de descripción de error

desc = oErrors.GetErrorDesc(codigo)! Retorna descripción en español

FiscalErrors contiene un catálogo de más de 200 códigos de error clasificados en categorías: Sistema, E/S, Socket, XML, JSON, Criptografía, Imagen, POS, Auditoría, Memoria Fiscal, Aritmética, Base de Datos, Protocolo e Interfaz.


11. Logging (FiscalLog)

El sistema de logging registra todos los comandos enviados y respuestas recibidas.

Configuración

! Habilitar via variable de entorno (ZVar_GetAndSet)
ZVar_GetAndSet('Fiscal.Log',1)! 1 = activo, 0 = inactivo! O directamente via FiscalConfig:
oConfig.SetLogEnable(1)
oConfig.SetLogFilename('C:\Logs\fiscal')

Nombre del archivo de log

{ruta_base}_{serie}_{YYYY}_{MM}.log
Ejemplo: C:\Logs\fiscal_A12345678_2026_04.log

Formato de entrada

[2026-04-24 14:32:10] → {"AbrirComprobante":{...}}
[2026-04-24 14:32:11] ← {"AbrirComprobante":{"Secuencia":"12345",...}}

Uso programático (raramente necesario directamente)

oLog.Init(oConfig)
oLog.Write('Mensaje de texto plano')
oLog.Write(cstring_var)

Los comandos de FiscalCommand llaman a FiscalLog automáticamente en cada envío/respuesta.


12. Protocolo JSON

Formato de solicitud

{
"NombreComando": {
"Parametro1": "valor1",
"Parametro2": "valor2"
}
}

Formato de respuesta — Éxito

{
"NombreComando": {
"Secuencia": "12345",
"Estado": {
"Impresora": ["estado1", "estado2"],
"Fiscal": ["estadoFiscal1"]
},
"CamposEspecificos": "..."
}
}

Formato de respuesta — Controlador ocupado

{
"ControladorOcupado": {
"Secuencia": "12345",
"Estado": { ... }
}
}

Cuando el controlador responde ControladorOcupado, FiscalCommand entra en bucle de reintento automático. La frecuencia y cantidad de reintentos son configurables. Durante la espera, se invoca el callback MyNotifyClass que activa la animación de PulseBarClass.

Formato de respuesta — Error

{
"Error": {
"Identificador": "CODIGO_ERROR",
"Descripcion": "Descripción del error",
"Contexto": "Información adicional"
}
}

13. Flujo de trabajo completo

Ejemplo mínimo: Factura B

! 1. Crear y configurar el coordinador de conexión
oFiscal.SetPDF(idPuntDeVenta)
oFiscal.SetConnectionString(connStr)IF NOT oFiscal.Open()Message('Error al conectar con el controlador fiscal')RETURNEND! 2. Crear el orquestador
oOrch.Init('Emisión Factura B')! 3. Datos del receptor
oOrch.Cliente('20304050607','Juan Perez','Av. Corrientes 1234', IVA_Consumidor_Final)! 4. Tipo de comprobante
oOrch.Titulo(Doc_FacturaB,1,'')! 5. Ítems
oOrch.Item('Producto A',2,1500.00, IVA_Gravado,21.00,'001')
oOrch.Item('Producto B',1,800.50, IVA_Gravado,10.50,'002')! 6. Pago
oOrch.Pago(Pay_Efectivo,3800.50,'')! 7. Cerrar el comprobante
oOrch.Cierre()! 8. Ejecutar (muestra ventana de progreso)
oOrch.Run()

Ejemplo: Cierre Z diario

! Solo ejecutar si se confirmó con el operadorIFMessage('¿Confirma el Cierre Z?','Cierre Diario',BUTTON:YesNo)=BUTTON:Yes
oCierreZ.Init(oConfig)IF oCierreZ.Run()= FISCAL_OK
Message('Cierre Z N° '& oCierreZ.GetNroZ()&' realizado correctamente.')ELSEMessage('Error en Cierre Z: '& oCierreZ.GetLastError())ENDEND

Ejemplo: Auditoría por fecha

 oAudit.Init(oConfig)
oAudit.SetFechaDesde('20260101')
oAudit.SetFechaHasta('20260131')IF oAudit.Run()<> FISCAL_OK
Message('Error de auditoría: '& oAudit.GetLastError())END

14. Referencia de bases de datos

Tabla pdf_config

CampoTipoDescripción
id_pdfLONGIdentificador del punto de venta
ipSTRINGIP del controlador fiscal (ej: "192.168.1.50")

Tabla pdf_fiscales

CampoTipoDescripción
serieSTRINGNúmero de serie del controlador
prefijoSTRINGPrefijo del punto de venta (ej: "0001")
marcaLONG1=Epson, 2=Hasar, 9=Virtual
modeloLONGConstante Fiscal_Type (ver sección 9)
if_ncLONGFlag de notas de crédito

Consultas ejecutadas por FiscalClass

-- LoadIP()SELECT ip FROM pdf_config WHERE id_pdf = :pdf
-- LoadParams() (tras obtener serial del controlador)SELECT prefijo, marca, modelo, if_nc
FROM pdf_fiscales
WHERE serie = :serial

Versión

La constante FISCAL_VERSION (definida en FiscalTypes.inc) identifica la versión de la biblioteca.

Formato:YY.MM.DDX

ParteDescripciónEjemplo
YYAño (2 dígitos)26
MMMes (2 dígitos)04
DDDía (2 dígitos)25
XRevisión del día (letra: A, B, C…)A

Historial

VersiónCambios
26.04.25APrimera versión pública

Notas para el desarrollador

  • Nunca instanciar FiscalConfig directamente: es un singleton. Acceder siempre a través de su instancia global.
  • El Cierre Z es irreversible: validar siempre con el operador antes de ejecutarlo.
  • LibCurl debe estar en el PATH o en la carpeta del ejecutable: sin él, todos los comandos fallan con HTTP:CURL_ERROR.
  • El logging crea un archivo por mes: monitorear espacio en disco en instalaciones con alto volumen de comprobantes.
  • FiscalOrchestra.Run() es bloqueante: abre una ventana modal. Si se necesita integración en un proceso batch sin UI, ejecutar los comandos directamente vía sus clases concretas.
  • Reintentos por ControladorOcupado: el controlador puede estar procesando un trabajo anterior. FiscalCommand reintenta automáticamente; el desarrollador puede configurar el número de intentos y el delay entre ellos.

About

Hasar Fiscal Printer Driver

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - gsaracca/FiscalClass: Hasar Fiscal Printer Driver · GitHub
Skip to content

Latest commit

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

FiscalClass — Biblioteca Clarion para Controladores Fiscales

Biblioteca de clases Clarion para integración con controladores fiscales electrónicos argentinos. Gestiona la comunicación HTTP/JSON con la impresora, el ciclo de vida completo de comprobantes (facturas, notas de crédito, cierres), auditoría y logging.

Autor: Gustavo Saracca
Plataforma: Clarion (CLW/INC)
Contacto:gsaracca@gmail.comPaís: Argentina — Controladores fiscales homologados AFIP
Licencia:MIT


Índice

  1. Requisitos y dependencias
  2. Estructura de archivos
  3. Arquitectura general
  4. Configuración inicial (FiscalConfig)
  5. Inicialización de conexión (FiscalClass)
  6. Capa de transporte HTTP (FiscalHTTP)
  7. Comandos disponibles
  8. Orquestador de documentos (FiscalOrchestra)
  9. Tipos y enumeraciones (FiscalTypes)
  10. Manejo de errores (FiscalErrors)
  11. Logging (FiscalLog)
  12. Protocolo JSON
  13. Flujo de trabajo completo
  14. Referencia de bases de datos

1. Requisitos y dependencias

Bibliotecas externas requeridas

ArchivoPropósito
LibCurl.inc / LibCurl.libComunicación HTTP (POST al controlador fiscal)
cJson.inc / cJson.libSerialización/deserialización JSON
..\access\access.libUtilidades de base de datos y presentación de mensajes
..\group\group.libGestión de variables globales (ZVar_GetAndSet)

Wrapper Clarion para la biblioteca libcurl, que permite realizar peticiones HTTP/HTTPS desde código Clarion nativo. FiscalClass la utiliza a través de TCurlClass para enviar los comandos JSON al controlador fiscal mediante HTTP POST al endpoint http://<ip>/fiscal.json. Es un requisito indispensable: sin esta biblioteca, todos los comandos fallan con HTTP:CURL_ERROR.

La DLL libcurl.dll debe estar disponible en el PATH del sistema o en la carpeta del ejecutable.

Wrapper Clarion para el parser cJSON, que provee serialización y deserialización de documentos JSON. FiscalClass lo utiliza para construir los payloads de cada comando (solicitudes) y para interpretar las respuestas del controlador fiscal (éxito, error, ControladorOcupado). Sin esta biblioteca no es posible comunicarse con el controlador, ya que el protocolo completo está basado en JSON.

Variables globales requeridas (via ZVar_GetAndSet)

VariableTipoDescripción
Fiscal.LogLONG1 = logging habilitado, 0 = deshabilitado

Tabla SQL requerida: pdf_config

-- Mapea cada punto de venta (PDF) a la IP del controlador fiscal
pdf_config (
id_pdf -- Identificador del punto de venta
ip -- Dirección IP del controlador fiscal (ej: "192.168.1.50")
)

Tabla SQL requerida: pdf_fiscales

-- Mapea el número de serie fiscal a configuración del punto de venta
pdf_fiscales (
serie -- Número de serie del controlador (ej: "A12345678")
prefijo -- Prefijo del comprobante (ej: "0001")
marca -- 1=Epson, 2=Hasar, 9=Virtual
modelo -- Ver enumeración Fiscal_Type en FiscalTypes.inc
if_nc -- Flag notas de crédito
)

2. Estructura de archivos

FiscalClass/
│
├── FiscalTypes.inc ← Enumeraciones y constantes globales
│
├── FiscalConfig.clw / .inc ← Singleton de configuración global
├── FiscalLog.clw / .inc ← Subsistema de logging
├── FiscalErrors.clw / .inc ← Registro de códigos de error
├── FiscalTools.clw / .inc ← Utilidades (zonas, flags de texto)
│
├── FiscalHTTP.clw / .inc ← Capa HTTP con LibCurl
├── FiscalCommand.clw / .inc ← Clase base de comandos + lógica de reintentos
│
├── FiscalClass.clw / .inc ← Coordinador principal (conexión, inicialización)
│
│ ── Comandos específicos ──
├── FiscalInicializacion.clw / .inc ← Consulta datos del controlador
├── FiscalConsultarEstado.clw / .inc ← Estado actual del controlador
├── FiscalCancelar.clw / .inc ← Cancelar operación en curso
├── FiscalCierreX.clw / .inc ← Informe X (subtotal sin borrar)
├── FiscalCierreZ.clw / .inc ← Cierre Z (cierre diario definitivo)
├── FiscalAuditDate.clw / .inc ← Auditoría por rango de fechas
├── FiscalAuditNumber.clw / .inc ← Auditoría por rango de número Z
├── FiscalCopiarComprobante.clw / .inc← Reimpresión de comprobante
│
├── FiscalOrchestra.clw / .inc ← Orquestador de alto nivel (workflow completo)
├── FiscalMail.clw ← Envío de documentos por correo
│
└── PulseBarClass.clw / .inc ← Control visual de progreso (barra animada)

3. Arquitectura general

La biblioteca está organizada en capas bien definidas:

┌─────────────────────────────────────────────────────┐
│ FiscalOrchestra │ ← Capa de aplicación
│ (workflow, UI, cola de comandos) │
└─────────────────┬───────────────────────────────────┘
│ usa
┌─────────────────▼───────────────────────────────────┐
│ FiscalInicializacion FiscalCierreZ FiscalCierreX │ ← Comandos concretos
│ FiscalConsultarEstado FiscalCancelar FiscalAudit… │
└─────────────────┬───────────────────────────────────┘
│ heredan
┌─────────────────▼───────────────────────────────────┐
│ FiscalCommand / FiscalCommandClass │ ← Base: JSON + reintentos
└─────────────────┬───────────────────────────────────┘
│ hereda
┌─────────────────▼───────────────────────────────────┐
│ FiscalHTTP │ ← HTTP POST via LibCurl
└─────────────────────────────────────────────────────┘
Transversal a todas las capas:
FiscalConfig (singleton de configuración)
FiscalLog (logging a archivo)
FiscalErrors (catálogo de errores)

Jerarquía de herencia de clases

FiscalHTTP
└─ FiscalCommandClass
└─ FiscalCommand (wrapper con reintentos automáticos)
├─ FiscalInicializacion
├─ FiscalConsultarEstado
├─ FiscalCancelar
├─ FiscalCierreX
├─ FiscalCierreZ
├─ FiscalAuditDate
├─ FiscalAuditNumber
└─ FiscalCopiarComprobante

4. Configuración inicial (FiscalConfig)

FiscalConfig es un objeto global singleton (instancia única compartida). No debe ser instanciado manualmente; se accede a través de su instancia global.

Propiedades configurables

MétodoDescripción
SetIP(string)IP del controlador fiscal
SetSerial(string)Número de serie del controlador
SetMarca(long)Marca: 1=Epson, 2=Hasar, 9=Virtual
SetModelo(long)Modelo (ver Fiscal_Type en FiscalTypes.inc)
SetPrefijo(string)Prefijo del punto de venta (ej: "0001")
SetNC(long)Flag notas de crédito
SetIIBB(string)Número de inscripción IIBB
SetCondIVA(long)Condición frente al IVA
SetLogEnable(long)Habilitar/deshabilitar logging
SetLogFilename(string)Ruta base del archivo de log
SetMsgBox(long)Controla presentación de mensajes

Mapeo de marca a string

1 → "Epson"
2 → "Hasar"
9 → "Virtual"

Mapeo de modelo a string

Fiscal_TM2000AF → "TM2000AF"
Fiscal_TM2000AFplus→ "TM2000AF+"
Fiscal_TMU220AF → "TMU220AF"
Fiscal_ND_3 → "N/A-3"
Fiscal_ND_5 → "N/A-5"
Fiscal_LX300 → "LX-300"
Fiscal_Hasar_441 → "441"
Fiscal_Hasar_1000 → "1000"

5. Inicialización de conexión (FiscalClass)

FiscalClass coordina la inicialización completa leyendo la configuración desde la base de datos.

Métodos principales

MétodoDescripción
SetPDF(long)Define el ID del punto de venta
SetConnectionString(string)Cadena de conexión SQL
Open()Ejecuta el flujo completo de inicialización
LoadIP()Lee la IP desde pdf_config
LoadFiscal()Consulta el controlador y carga serial/prefijo
LoadParams()Lee marca y modelo desde pdf_fiscales

Flujo de Open()

Open()
├─ LoadIP() → Lee ip de pdf_config WHERE id_pdf = @pdf
├─ LoadFiscal() → Ejecuta FiscalInicializacion, guarda serial/prefijo
└─ LoadParams() → Lee marca/modelo de pdf_fiscales WHERE serie = @serial

Atributos disponibles tras Open()

oFiscal.GetPDF()! ID del punto de venta
oFiscal.GetPrefijo()! Prefijo cargado desde controlador
oFiscal.GetConfigPrefijo()! Prefijo cargado desde base de datos

6. Capa de transporte HTTP (FiscalHTTP)

FiscalHTTP encapsula la comunicación HTTP POST usando TCurlClass (LibCurl).

Endpoint

POST http://<ip>/fiscal.json
Content-Type: application/json

Atributos de resultado

AtributoDescripción
HTTPCodeCódigo de respuesta HTTP
HTTPMessageCuerpo de la respuesta (JSON)
HTTPErrorCódigo de error interno

Códigos de error HTTP internos

HTTP:CURL_OK =0! ExitosoHTTP:CURL_ERROR =1! Error de LibCurlHTTP:NET_ERROR =2! Respuesta HTTP 3xx-5xx

7. Comandos disponibles

Todos los comandos heredan de FiscalCommand e implementan el método Run().

7.1 FiscalInicializacion

Consulta los datos de identificación del controlador fiscal.

Respuesta relevante:

  • CUIT del emisor
  • Razón social
  • Número de serie
  • Prefijo del punto de venta
oInit.Init(oConfig)IF oInit.Run()= FISCAL_OK
serial = oInit.GetSerial()
prefijo = oInit.GetPrefijo()
cuit = oInit.GetCUIT()END

7.2 FiscalConsultarEstado

Obtiene el estado actual del controlador y el último comprobante emitido.

oEstado.Init(oConfig)IF oEstado.Run()= FISCAL_OK
estado = oEstado.GetEstado()
ultimo = oEstado.GetUltimoComprobante()END

7.3 FiscalCancelar

Cancela la operación en curso en el controlador.

oCancel.Init(oConfig)
oCancel.Run()

7.4 FiscalCierreX — Informe X

Emite un informe de subtotales sin borrar la memoria fiscal. Equivale a un "corte X" en terminología fiscal.

oCierreX.Init(oConfig)IF oCierreX.Run()= FISCAL_OK
! Informe impreso en el controladorEND

7.5 FiscalCierreZ — Cierre diario

Emite el cierre diario definitivo. Borra los acumuladores y avanza el contador Z.

oCierreZ.Init(oConfig)IF oCierreZ.Run()= FISCAL_OK
nroZ = oCierreZ.GetNroZ()
totalZ = oCierreZ.GetTotal()END

Importante: Esta operación es irreversible. El controlador fiscal homologado no permite anular un cierre Z.

7.6 FiscalAuditDate — Auditoría por fecha

Imprime el informe de auditoría para un rango de fechas.

oAudit.Init(oConfig)
oAudit.SetFechaDesde('20260101')
oAudit.SetFechaHasta('20260131')
oAudit.Run()

7.7 FiscalAuditNumber — Auditoría por número Z

Imprime el informe de auditoría para un rango de números de cierre Z.

oAuditN.Init(oConfig)
oAuditN.SetZDesde(100)
oAuditN.SetZHasta(150)
oAuditN.Run()

7.8 FiscalCopiarComprobante

Reimprime una copia de un comprobante emitido.

oCopia.Init(oConfig)
oCopia.SetNumeroComprobante(12345)
oCopia.Run()

8. Orquestador de documentos (FiscalOrchestra)

FiscalOrchestra es el componente de más alto nivel. Gestiona el ciclo de vida completo de un comprobante fiscal, acumulando comandos en una cola y ejecutándolos con una UI de progreso.

Inicialización

oOrch.Init('Emisión Factura B')! Título visible en la ventana de progreso
oOrch.SetConfig(oConfig)

Métodos de construcción del documento

Cliente (datos del receptor)

oOrch.Cliente(
cuit,! CUIT del cliente (string, sin guiones)
razonSocial,! Razón social o nombre
domicilio,! Domicilio completo
condIVA ! Ver FiscalCondIVA en FiscalTypes.inc)

Título (cabecera del comprobante)

oOrch.Titulo(
tipoDoc,! Ver FiscalDocType en FiscalTypes.inc (ej: Doc_FacturaB)
copias,! Cantidad de copias a imprimir
referencia ! Número de comprobante de referencia (para NC/ND))

Ítem (líneas del cuerpo)

oOrch.Item(
descripcion,! Texto de la línea
cantidad,! Cantidad (DECIMAL)
precioUnitario,! Precio unitario (DECIMAL)
ivaCondicion,! Ver FiscalIVACond (Gravado, Exento, NoGravado)
ivaAlicuota,! Alícuota de IVA (ej: 21.00)
codigoProducto ! Código interno del producto)

Pago

oOrch.Pago(
medioPago,! Ver FiscalPayment en FiscalTypes.inc
importe,! Importe del pago (DECIMAL)
descripcion ! Descripción opcional)

Percepción

oOrch.Percepcion(
tipoImpuesto,! Ver FiscalTaxType
alicuota,! Alícuota
importe ! Importe percibido)

Bonificación / Descuento

oOrch.Bonif(
descripcion,
importe,! Positivo = descuento, negativo = recargo
ivaCondicion
)

Ajuste

oOrch.Ajuste(descripcion, importe)

Cierre del comprobante

oOrch.Cierre()

Sección no fiscal (textos sin efecto fiscal)

oOrch.TituloNF(texto)! Título de sección no fiscal
oOrch.TextoNF(texto)! Línea de texto libre
oOrch.CierreNF()! Cierre de sección no fiscal

Zonas de texto (header/footer del comprobante)

oOrch.ZonaHead(texto, atributos)! Encabezado del ticket
oOrch.ZonaFoot(texto, atributos)! Pie del ticket
oOrch.ZonaDomicilioEmisor(texto)! Domicilio del emisor
oOrch.ZonaFantasia(texto)! Nombre de fantasía

Los atributos de texto se combinan con OR de bit usando las constantes de FiscalTextAttr:

! Ejemplo: texto centrado y negritaattr = FiscalAttr_Centered |: FiscalAttr_Bold
oOrch.ZonaHead('MI EMPRESA S.A.', attr)

Ejecución

oOrch.Run()! Abre ventana de progreso y ejecuta toda la cola de comandos

Run() muestra una ventana modal con:

  • Lista de comandos pendientes / ejecutados
  • Barra animada de progreso (PulseBarClass) durante reintentos
  • Botón cancelar (pregunta confirmación antes de abortar)

Ventana de progreso del orquestador

Cancelación

oOrch.Cancelar()! Cancela la operación en curso en el controlador
oOrch.AskAbort()! Pide confirmación al usuario antes de cancelar

9. Tipos y enumeraciones (FiscalTypes)

Todas las constantes están definidas en FiscalTypes.inc.

Tipos de controlador (Fiscal_Type)

Fiscal_TM2000AF ! Epson TM-2000AF
Fiscal_TM2000AFplus! Epson TM-2000AF+Fiscal_TMU220AF ! Epson TM-U220AFFiscal_ND_3 ! Genérico N/A-3Fiscal_ND_5 ! Genérico N/A-5Fiscal_LX300 ! Epson LX-300Fiscal_Hasar_441 ! Hasar 441Fiscal_Hasar_1000 ! Hasar 1000

Tipos de documento (FiscalDocType)

Doc_FacturaA  Doc_FacturaB Doc_FacturaC
Doc_NotaDeCreditoA  Doc_NotaDeCreditoB Doc_NotaDeCreditoC
Doc_NotaDeDebitoA  Doc_NotaDeDebitoB Doc_NotaDeDebitoC
Doc_ReciboA  Doc_ReciboB Doc_ReciboC
Doc_TiqueFacturaA  Doc_TiqueFacturaB Doc_TiqueFacturaC
Doc_TiqueNotaCreditoDoc_InformeDiarioDeCierre ! Cierre ZDoc_DetalleDeVentas ! Informe XDoc_Remito  Doc_Presupuesto Doc_MensajeCF
Doc_ComprobanteDonacion! ... y más de 40 tipos en total

Condición IVA del ítem (FiscalIVACond)

IVA_GravadoIVA_ExentoIVA_NoGravado

Responsabilidad IVA del emisor/receptor (FiscalCondIVA)

IVA_ResponsableInscriptoIVA_ExentoIVA_NoResponsableIVA_MonotributoIVA_ResponsableMonotributoIVA_GranContribuyenteIVA_Consumidor_Final

Medios de pago (FiscalPayment)

Pay_Efectivo  Pay_Cheque
Pay_TarjetaCredito  Pay_TarjetaDebito
Pay_TransferenciaBancaria Pay_CuentaCorriente
Pay_Vales  Pay_Otro
! ... más de 30 tipos

Tipos de impuesto adicional (FiscalTaxType)

Tax_Nacional  Tax_Provincial Tax_Municipal
Tax_Interno  Tax_IIBB Tax_PercepcionIVA

Atributos de texto (FiscalTextAttr) — flags de bit

FiscalAttr_Deleted =01H! TachadoFiscalAttr_Wide =02H! Ancho dobleFiscalAttr_Centered =04H! CentradoFiscalAttr_Bold =08H! Negrita

Estaciones de impresión (FiscalStation)

Station_TicketStation_SlipStation_Default

Zonas del comprobante (FiscalZone)

Zone_Fantasia ! Nombre de fantasíaZone_Domicilio ! Domicilio del emisorZone_Header1 ! Encabezado línea 1Zone_Header2 ! Encabezado línea 2Zone_Footer1 ! Pie línea 1Zone_Footer2 ! Pie línea 2

10. Manejo de errores (FiscalErrors)

Flags de estado (combinables con OR de bit)

FISCAL_OK =000H! Sin erroresFISCAL_ERROR =001H! Error genéricoFISCAL_PRINTER_ERROR =002H! Error físico de impresoraFISCAL_SYNTAX_ERROR =004H! Error de sintaxis de comandoFISCAL_NET_ERROR =008H! Error de red/HTTPFISCAL_BUSY =010H! Controlador ocupadoFISCAL_RESPONSE_ERROR =020H! Respuesta inesperadaFISCAL_UNKNOWN =040H! Estado desconocidoFISCAL_UNKNOWN_COMMAND =080H! Comando no reconocidoFISCAL_AUX =100H! Mensaje auxiliarFISCAL_INTERNAL =200H! Error interno del controlador

Categorías de mensajes del controlador

Los mensajes del controlador están catalogados en rangos numéricos:

RangoCategoría
101–116FISCAL_PRINTER_ERROR — Error físico de impresora
201–216FISCAL_ERROR — Error fiscal/lógico
301–307FISCAL_AUX — Mensajes auxiliares informativos
400–417FISCAL_INTERNAL — Errores internos del controlador

Consulta de descripción de error

desc = oErrors.GetErrorDesc(codigo)! Retorna descripción en español

FiscalErrors contiene un catálogo de más de 200 códigos de error clasificados en categorías: Sistema, E/S, Socket, XML, JSON, Criptografía, Imagen, POS, Auditoría, Memoria Fiscal, Aritmética, Base de Datos, Protocolo e Interfaz.


11. Logging (FiscalLog)

El sistema de logging registra todos los comandos enviados y respuestas recibidas.

Configuración

! Habilitar via variable de entorno (ZVar_GetAndSet)
ZVar_GetAndSet('Fiscal.Log',1)! 1 = activo, 0 = inactivo! O directamente via FiscalConfig:
oConfig.SetLogEnable(1)
oConfig.SetLogFilename('C:\Logs\fiscal')

Nombre del archivo de log

{ruta_base}_{serie}_{YYYY}_{MM}.log
Ejemplo: C:\Logs\fiscal_A12345678_2026_04.log

Formato de entrada

[2026-04-24 14:32:10] → {"AbrirComprobante":{...}}
[2026-04-24 14:32:11] ← {"AbrirComprobante":{"Secuencia":"12345",...}}

Uso programático (raramente necesario directamente)

oLog.Init(oConfig)
oLog.Write('Mensaje de texto plano')
oLog.Write(cstring_var)

Los comandos de FiscalCommand llaman a FiscalLog automáticamente en cada envío/respuesta.


12. Protocolo JSON

Formato de solicitud

{
"NombreComando": {
"Parametro1": "valor1",
"Parametro2": "valor2"
}
}

Formato de respuesta — Éxito

{
"NombreComando": {
"Secuencia": "12345",
"Estado": {
"Impresora": ["estado1", "estado2"],
"Fiscal": ["estadoFiscal1"]
},
"CamposEspecificos": "..."
}
}

Formato de respuesta — Controlador ocupado

{
"ControladorOcupado": {
"Secuencia": "12345",
"Estado": { ... }
}
}

Cuando el controlador responde ControladorOcupado, FiscalCommand entra en bucle de reintento automático. La frecuencia y cantidad de reintentos son configurables. Durante la espera, se invoca el callback MyNotifyClass que activa la animación de PulseBarClass.

Formato de respuesta — Error

{
"Error": {
"Identificador": "CODIGO_ERROR",
"Descripcion": "Descripción del error",
"Contexto": "Información adicional"
}
}

13. Flujo de trabajo completo

Ejemplo mínimo: Factura B

! 1. Crear y configurar el coordinador de conexión
oFiscal.SetPDF(idPuntDeVenta)
oFiscal.SetConnectionString(connStr)IF NOT oFiscal.Open()Message('Error al conectar con el controlador fiscal')RETURNEND! 2. Crear el orquestador
oOrch.Init('Emisión Factura B')! 3. Datos del receptor
oOrch.Cliente('20304050607','Juan Perez','Av. Corrientes 1234', IVA_Consumidor_Final)! 4. Tipo de comprobante
oOrch.Titulo(Doc_FacturaB,1,'')! 5. Ítems
oOrch.Item('Producto A',2,1500.00, IVA_Gravado,21.00,'001')
oOrch.Item('Producto B',1,800.50, IVA_Gravado,10.50,'002')! 6. Pago
oOrch.Pago(Pay_Efectivo,3800.50,'')! 7. Cerrar el comprobante
oOrch.Cierre()! 8. Ejecutar (muestra ventana de progreso)
oOrch.Run()

Ejemplo: Cierre Z diario

! Solo ejecutar si se confirmó con el operadorIFMessage('¿Confirma el Cierre Z?','Cierre Diario',BUTTON:YesNo)=BUTTON:Yes
oCierreZ.Init(oConfig)IF oCierreZ.Run()= FISCAL_OK
Message('Cierre Z N° '& oCierreZ.GetNroZ()&' realizado correctamente.')ELSEMessage('Error en Cierre Z: '& oCierreZ.GetLastError())ENDEND

Ejemplo: Auditoría por fecha

 oAudit.Init(oConfig)
oAudit.SetFechaDesde('20260101')
oAudit.SetFechaHasta('20260131')IF oAudit.Run()<> FISCAL_OK
Message('Error de auditoría: '& oAudit.GetLastError())END

14. Referencia de bases de datos

Tabla pdf_config

CampoTipoDescripción
id_pdfLONGIdentificador del punto de venta
ipSTRINGIP del controlador fiscal (ej: "192.168.1.50")

Tabla pdf_fiscales

CampoTipoDescripción
serieSTRINGNúmero de serie del controlador
prefijoSTRINGPrefijo del punto de venta (ej: "0001")
marcaLONG1=Epson, 2=Hasar, 9=Virtual
modeloLONGConstante Fiscal_Type (ver sección 9)
if_ncLONGFlag de notas de crédito

Consultas ejecutadas por FiscalClass

-- LoadIP()SELECT ip FROM pdf_config WHERE id_pdf = :pdf
-- LoadParams() (tras obtener serial del controlador)SELECT prefijo, marca, modelo, if_nc
FROM pdf_fiscales
WHERE serie = :serial

Versión

La constante FISCAL_VERSION (definida en FiscalTypes.inc) identifica la versión de la biblioteca.

Formato:YY.MM.DDX

ParteDescripciónEjemplo
YYAño (2 dígitos)26
MMMes (2 dígitos)04
DDDía (2 dígitos)25
XRevisión del día (letra: A, B, C…)A

Historial

VersiónCambios
26.04.25APrimera versión pública

Notas para el desarrollador

  • Nunca instanciar FiscalConfig directamente: es un singleton. Acceder siempre a través de su instancia global.
  • El Cierre Z es irreversible: validar siempre con el operador antes de ejecutarlo.
  • LibCurl debe estar en el PATH o en la carpeta del ejecutable: sin él, todos los comandos fallan con HTTP:CURL_ERROR.
  • El logging crea un archivo por mes: monitorear espacio en disco en instalaciones con alto volumen de comprobantes.
  • FiscalOrchestra.Run() es bloqueante: abre una ventana modal. Si se necesita integración en un proceso batch sin UI, ejecutar los comandos directamente vía sus clases concretas.
  • Reintentos por ControladorOcupado: el controlador puede estar procesando un trabajo anterior. FiscalCommand reintenta automáticamente; el desarrollador puede configurar el número de intentos y el delay entre ellos.

About

Hasar Fiscal Printer Driver

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - gsaracca/FiscalClass: Hasar Fiscal Printer Driver · GitHub
Skip to content

Latest commit

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

FiscalClass — Biblioteca Clarion para Controladores Fiscales

Biblioteca de clases Clarion para integración con controladores fiscales electrónicos argentinos. Gestiona la comunicación HTTP/JSON con la impresora, el ciclo de vida completo de comprobantes (facturas, notas de crédito, cierres), auditoría y logging.

Autor: Gustavo Saracca
Plataforma: Clarion (CLW/INC)
Contacto:gsaracca@gmail.comPaís: Argentina — Controladores fiscales homologados AFIP
Licencia:MIT


Índice

  1. Requisitos y dependencias
  2. Estructura de archivos
  3. Arquitectura general
  4. Configuración inicial (FiscalConfig)
  5. Inicialización de conexión (FiscalClass)
  6. Capa de transporte HTTP (FiscalHTTP)
  7. Comandos disponibles
  8. Orquestador de documentos (FiscalOrchestra)
  9. Tipos y enumeraciones (FiscalTypes)
  10. Manejo de errores (FiscalErrors)
  11. Logging (FiscalLog)
  12. Protocolo JSON
  13. Flujo de trabajo completo
  14. Referencia de bases de datos

1. Requisitos y dependencias

Bibliotecas externas requeridas

ArchivoPropósito
LibCurl.inc / LibCurl.libComunicación HTTP (POST al controlador fiscal)
cJson.inc / cJson.libSerialización/deserialización JSON
..\access\access.libUtilidades de base de datos y presentación de mensajes
..\group\group.libGestión de variables globales (ZVar_GetAndSet)

Wrapper Clarion para la biblioteca libcurl, que permite realizar peticiones HTTP/HTTPS desde código Clarion nativo. FiscalClass la utiliza a través de TCurlClass para enviar los comandos JSON al controlador fiscal mediante HTTP POST al endpoint http://<ip>/fiscal.json. Es un requisito indispensable: sin esta biblioteca, todos los comandos fallan con HTTP:CURL_ERROR.

La DLL libcurl.dll debe estar disponible en el PATH del sistema o en la carpeta del ejecutable.

Wrapper Clarion para el parser cJSON, que provee serialización y deserialización de documentos JSON. FiscalClass lo utiliza para construir los payloads de cada comando (solicitudes) y para interpretar las respuestas del controlador fiscal (éxito, error, ControladorOcupado). Sin esta biblioteca no es posible comunicarse con el controlador, ya que el protocolo completo está basado en JSON.

Variables globales requeridas (via ZVar_GetAndSet)

VariableTipoDescripción
Fiscal.LogLONG1 = logging habilitado, 0 = deshabilitado

Tabla SQL requerida: pdf_config

-- Mapea cada punto de venta (PDF) a la IP del controlador fiscal
pdf_config (
id_pdf -- Identificador del punto de venta
ip -- Dirección IP del controlador fiscal (ej: "192.168.1.50")
)

Tabla SQL requerida: pdf_fiscales

-- Mapea el número de serie fiscal a configuración del punto de venta
pdf_fiscales (
serie -- Número de serie del controlador (ej: "A12345678")
prefijo -- Prefijo del comprobante (ej: "0001")
marca -- 1=Epson, 2=Hasar, 9=Virtual
modelo -- Ver enumeración Fiscal_Type en FiscalTypes.inc
if_nc -- Flag notas de crédito
)

2. Estructura de archivos

FiscalClass/
│
├── FiscalTypes.inc ← Enumeraciones y constantes globales
│
├── FiscalConfig.clw / .inc ← Singleton de configuración global
├── FiscalLog.clw / .inc ← Subsistema de logging
├── FiscalErrors.clw / .inc ← Registro de códigos de error
├── FiscalTools.clw / .inc ← Utilidades (zonas, flags de texto)
│
├── FiscalHTTP.clw / .inc ← Capa HTTP con LibCurl
├── FiscalCommand.clw / .inc ← Clase base de comandos + lógica de reintentos
│
├── FiscalClass.clw / .inc ← Coordinador principal (conexión, inicialización)
│
│ ── Comandos específicos ──
├── FiscalInicializacion.clw / .inc ← Consulta datos del controlador
├── FiscalConsultarEstado.clw / .inc ← Estado actual del controlador
├── FiscalCancelar.clw / .inc ← Cancelar operación en curso
├── FiscalCierreX.clw / .inc ← Informe X (subtotal sin borrar)
├── FiscalCierreZ.clw / .inc ← Cierre Z (cierre diario definitivo)
├── FiscalAuditDate.clw / .inc ← Auditoría por rango de fechas
├── FiscalAuditNumber.clw / .inc ← Auditoría por rango de número Z
├── FiscalCopiarComprobante.clw / .inc← Reimpresión de comprobante
│
├── FiscalOrchestra.clw / .inc ← Orquestador de alto nivel (workflow completo)
├── FiscalMail.clw ← Envío de documentos por correo
│
└── PulseBarClass.clw / .inc ← Control visual de progreso (barra animada)

3. Arquitectura general

La biblioteca está organizada en capas bien definidas:

┌─────────────────────────────────────────────────────┐
│ FiscalOrchestra │ ← Capa de aplicación
│ (workflow, UI, cola de comandos) │
└─────────────────┬───────────────────────────────────┘
│ usa
┌─────────────────▼───────────────────────────────────┐
│ FiscalInicializacion FiscalCierreZ FiscalCierreX │ ← Comandos concretos
│ FiscalConsultarEstado FiscalCancelar FiscalAudit… │
└─────────────────┬───────────────────────────────────┘
│ heredan
┌─────────────────▼───────────────────────────────────┐
│ FiscalCommand / FiscalCommandClass │ ← Base: JSON + reintentos
└─────────────────┬───────────────────────────────────┘
│ hereda
┌─────────────────▼───────────────────────────────────┐
│ FiscalHTTP │ ← HTTP POST via LibCurl
└─────────────────────────────────────────────────────┘
Transversal a todas las capas:
FiscalConfig (singleton de configuración)
FiscalLog (logging a archivo)
FiscalErrors (catálogo de errores)

Jerarquía de herencia de clases

FiscalHTTP
└─ FiscalCommandClass
└─ FiscalCommand (wrapper con reintentos automáticos)
├─ FiscalInicializacion
├─ FiscalConsultarEstado
├─ FiscalCancelar
├─ FiscalCierreX
├─ FiscalCierreZ
├─ FiscalAuditDate
├─ FiscalAuditNumber
└─ FiscalCopiarComprobante

4. Configuración inicial (FiscalConfig)

FiscalConfig es un objeto global singleton (instancia única compartida). No debe ser instanciado manualmente; se accede a través de su instancia global.

Propiedades configurables

MétodoDescripción
SetIP(string)IP del controlador fiscal
SetSerial(string)Número de serie del controlador
SetMarca(long)Marca: 1=Epson, 2=Hasar, 9=Virtual
SetModelo(long)Modelo (ver Fiscal_Type en FiscalTypes.inc)
SetPrefijo(string)Prefijo del punto de venta (ej: "0001")
SetNC(long)Flag notas de crédito
SetIIBB(string)Número de inscripción IIBB
SetCondIVA(long)Condición frente al IVA
SetLogEnable(long)Habilitar/deshabilitar logging
SetLogFilename(string)Ruta base del archivo de log
SetMsgBox(long)Controla presentación de mensajes

Mapeo de marca a string

1 → "Epson"
2 → "Hasar"
9 → "Virtual"

Mapeo de modelo a string

Fiscal_TM2000AF → "TM2000AF"
Fiscal_TM2000AFplus→ "TM2000AF+"
Fiscal_TMU220AF → "TMU220AF"
Fiscal_ND_3 → "N/A-3"
Fiscal_ND_5 → "N/A-5"
Fiscal_LX300 → "LX-300"
Fiscal_Hasar_441 → "441"
Fiscal_Hasar_1000 → "1000"

5. Inicialización de conexión (FiscalClass)

FiscalClass coordina la inicialización completa leyendo la configuración desde la base de datos.

Métodos principales

MétodoDescripción
SetPDF(long)Define el ID del punto de venta
SetConnectionString(string)Cadena de conexión SQL
Open()Ejecuta el flujo completo de inicialización
LoadIP()Lee la IP desde pdf_config
LoadFiscal()Consulta el controlador y carga serial/prefijo
LoadParams()Lee marca y modelo desde pdf_fiscales

Flujo de Open()

Open()
├─ LoadIP() → Lee ip de pdf_config WHERE id_pdf = @pdf
├─ LoadFiscal() → Ejecuta FiscalInicializacion, guarda serial/prefijo
└─ LoadParams() → Lee marca/modelo de pdf_fiscales WHERE serie = @serial

Atributos disponibles tras Open()

oFiscal.GetPDF()! ID del punto de venta
oFiscal.GetPrefijo()! Prefijo cargado desde controlador
oFiscal.GetConfigPrefijo()! Prefijo cargado desde base de datos

6. Capa de transporte HTTP (FiscalHTTP)

FiscalHTTP encapsula la comunicación HTTP POST usando TCurlClass (LibCurl).

Endpoint

POST http://<ip>/fiscal.json
Content-Type: application/json

Atributos de resultado

AtributoDescripción
HTTPCodeCódigo de respuesta HTTP
HTTPMessageCuerpo de la respuesta (JSON)
HTTPErrorCódigo de error interno

Códigos de error HTTP internos

HTTP:CURL_OK =0! ExitosoHTTP:CURL_ERROR =1! Error de LibCurlHTTP:NET_ERROR =2! Respuesta HTTP 3xx-5xx

7. Comandos disponibles

Todos los comandos heredan de FiscalCommand e implementan el método Run().

7.1 FiscalInicializacion

Consulta los datos de identificación del controlador fiscal.

Respuesta relevante:

  • CUIT del emisor
  • Razón social
  • Número de serie
  • Prefijo del punto de venta
oInit.Init(oConfig)IF oInit.Run()= FISCAL_OK
serial = oInit.GetSerial()
prefijo = oInit.GetPrefijo()
cuit = oInit.GetCUIT()END

7.2 FiscalConsultarEstado

Obtiene el estado actual del controlador y el último comprobante emitido.

oEstado.Init(oConfig)IF oEstado.Run()= FISCAL_OK
estado = oEstado.GetEstado()
ultimo = oEstado.GetUltimoComprobante()END

7.3 FiscalCancelar

Cancela la operación en curso en el controlador.

oCancel.Init(oConfig)
oCancel.Run()

7.4 FiscalCierreX — Informe X

Emite un informe de subtotales sin borrar la memoria fiscal. Equivale a un "corte X" en terminología fiscal.

oCierreX.Init(oConfig)IF oCierreX.Run()= FISCAL_OK
! Informe impreso en el controladorEND

7.5 FiscalCierreZ — Cierre diario

Emite el cierre diario definitivo. Borra los acumuladores y avanza el contador Z.

oCierreZ.Init(oConfig)IF oCierreZ.Run()= FISCAL_OK
nroZ = oCierreZ.GetNroZ()
totalZ = oCierreZ.GetTotal()END

Importante: Esta operación es irreversible. El controlador fiscal homologado no permite anular un cierre Z.

7.6 FiscalAuditDate — Auditoría por fecha

Imprime el informe de auditoría para un rango de fechas.

oAudit.Init(oConfig)
oAudit.SetFechaDesde('20260101')
oAudit.SetFechaHasta('20260131')
oAudit.Run()

7.7 FiscalAuditNumber — Auditoría por número Z

Imprime el informe de auditoría para un rango de números de cierre Z.

oAuditN.Init(oConfig)
oAuditN.SetZDesde(100)
oAuditN.SetZHasta(150)
oAuditN.Run()

7.8 FiscalCopiarComprobante

Reimprime una copia de un comprobante emitido.

oCopia.Init(oConfig)
oCopia.SetNumeroComprobante(12345)
oCopia.Run()

8. Orquestador de documentos (FiscalOrchestra)

FiscalOrchestra es el componente de más alto nivel. Gestiona el ciclo de vida completo de un comprobante fiscal, acumulando comandos en una cola y ejecutándolos con una UI de progreso.

Inicialización

oOrch.Init('Emisión Factura B')! Título visible en la ventana de progreso
oOrch.SetConfig(oConfig)

Métodos de construcción del documento

Cliente (datos del receptor)

oOrch.Cliente(
cuit,! CUIT del cliente (string, sin guiones)
razonSocial,! Razón social o nombre
domicilio,! Domicilio completo
condIVA ! Ver FiscalCondIVA en FiscalTypes.inc)

Título (cabecera del comprobante)

oOrch.Titulo(
tipoDoc,! Ver FiscalDocType en FiscalTypes.inc (ej: Doc_FacturaB)
copias,! Cantidad de copias a imprimir
referencia ! Número de comprobante de referencia (para NC/ND))

Ítem (líneas del cuerpo)

oOrch.Item(
descripcion,! Texto de la línea
cantidad,! Cantidad (DECIMAL)
precioUnitario,! Precio unitario (DECIMAL)
ivaCondicion,! Ver FiscalIVACond (Gravado, Exento, NoGravado)
ivaAlicuota,! Alícuota de IVA (ej: 21.00)
codigoProducto ! Código interno del producto)

Pago

oOrch.Pago(
medioPago,! Ver FiscalPayment en FiscalTypes.inc
importe,! Importe del pago (DECIMAL)
descripcion ! Descripción opcional)

Percepción

oOrch.Percepcion(
tipoImpuesto,! Ver FiscalTaxType
alicuota,! Alícuota
importe ! Importe percibido)

Bonificación / Descuento

oOrch.Bonif(
descripcion,
importe,! Positivo = descuento, negativo = recargo
ivaCondicion
)

Ajuste

oOrch.Ajuste(descripcion, importe)

Cierre del comprobante

oOrch.Cierre()

Sección no fiscal (textos sin efecto fiscal)

oOrch.TituloNF(texto)! Título de sección no fiscal
oOrch.TextoNF(texto)! Línea de texto libre
oOrch.CierreNF()! Cierre de sección no fiscal

Zonas de texto (header/footer del comprobante)

oOrch.ZonaHead(texto, atributos)! Encabezado del ticket
oOrch.ZonaFoot(texto, atributos)! Pie del ticket
oOrch.ZonaDomicilioEmisor(texto)! Domicilio del emisor
oOrch.ZonaFantasia(texto)! Nombre de fantasía

Los atributos de texto se combinan con OR de bit usando las constantes de FiscalTextAttr:

! Ejemplo: texto centrado y negritaattr = FiscalAttr_Centered |: FiscalAttr_Bold
oOrch.ZonaHead('MI EMPRESA S.A.', attr)

Ejecución

oOrch.Run()! Abre ventana de progreso y ejecuta toda la cola de comandos

Run() muestra una ventana modal con:

  • Lista de comandos pendientes / ejecutados
  • Barra animada de progreso (PulseBarClass) durante reintentos
  • Botón cancelar (pregunta confirmación antes de abortar)

Ventana de progreso del orquestador

Cancelación

oOrch.Cancelar()! Cancela la operación en curso en el controlador
oOrch.AskAbort()! Pide confirmación al usuario antes de cancelar

9. Tipos y enumeraciones (FiscalTypes)

Todas las constantes están definidas en FiscalTypes.inc.

Tipos de controlador (Fiscal_Type)

Fiscal_TM2000AF ! Epson TM-2000AF
Fiscal_TM2000AFplus! Epson TM-2000AF+Fiscal_TMU220AF ! Epson TM-U220AFFiscal_ND_3 ! Genérico N/A-3Fiscal_ND_5 ! Genérico N/A-5Fiscal_LX300 ! Epson LX-300Fiscal_Hasar_441 ! Hasar 441Fiscal_Hasar_1000 ! Hasar 1000

Tipos de documento (FiscalDocType)

Doc_FacturaA  Doc_FacturaB Doc_FacturaC
Doc_NotaDeCreditoA  Doc_NotaDeCreditoB Doc_NotaDeCreditoC
Doc_NotaDeDebitoA  Doc_NotaDeDebitoB Doc_NotaDeDebitoC
Doc_ReciboA  Doc_ReciboB Doc_ReciboC
Doc_TiqueFacturaA  Doc_TiqueFacturaB Doc_TiqueFacturaC
Doc_TiqueNotaCreditoDoc_InformeDiarioDeCierre ! Cierre ZDoc_DetalleDeVentas ! Informe XDoc_Remito  Doc_Presupuesto Doc_MensajeCF
Doc_ComprobanteDonacion! ... y más de 40 tipos en total

Condición IVA del ítem (FiscalIVACond)

IVA_GravadoIVA_ExentoIVA_NoGravado

Responsabilidad IVA del emisor/receptor (FiscalCondIVA)

IVA_ResponsableInscriptoIVA_ExentoIVA_NoResponsableIVA_MonotributoIVA_ResponsableMonotributoIVA_GranContribuyenteIVA_Consumidor_Final

Medios de pago (FiscalPayment)

Pay_Efectivo  Pay_Cheque
Pay_TarjetaCredito  Pay_TarjetaDebito
Pay_TransferenciaBancaria Pay_CuentaCorriente
Pay_Vales  Pay_Otro
! ... más de 30 tipos

Tipos de impuesto adicional (FiscalTaxType)

Tax_Nacional  Tax_Provincial Tax_Municipal
Tax_Interno  Tax_IIBB Tax_PercepcionIVA

Atributos de texto (FiscalTextAttr) — flags de bit

FiscalAttr_Deleted =01H! TachadoFiscalAttr_Wide =02H! Ancho dobleFiscalAttr_Centered =04H! CentradoFiscalAttr_Bold =08H! Negrita

Estaciones de impresión (FiscalStation)

Station_TicketStation_SlipStation_Default

Zonas del comprobante (FiscalZone)

Zone_Fantasia ! Nombre de fantasíaZone_Domicilio ! Domicilio del emisorZone_Header1 ! Encabezado línea 1Zone_Header2 ! Encabezado línea 2Zone_Footer1 ! Pie línea 1Zone_Footer2 ! Pie línea 2

10. Manejo de errores (FiscalErrors)

Flags de estado (combinables con OR de bit)

FISCAL_OK =000H! Sin erroresFISCAL_ERROR =001H! Error genéricoFISCAL_PRINTER_ERROR =002H! Error físico de impresoraFISCAL_SYNTAX_ERROR =004H! Error de sintaxis de comandoFISCAL_NET_ERROR =008H! Error de red/HTTPFISCAL_BUSY =010H! Controlador ocupadoFISCAL_RESPONSE_ERROR =020H! Respuesta inesperadaFISCAL_UNKNOWN =040H! Estado desconocidoFISCAL_UNKNOWN_COMMAND =080H! Comando no reconocidoFISCAL_AUX =100H! Mensaje auxiliarFISCAL_INTERNAL =200H! Error interno del controlador

Categorías de mensajes del controlador

Los mensajes del controlador están catalogados en rangos numéricos:

RangoCategoría
101–116FISCAL_PRINTER_ERROR — Error físico de impresora
201–216FISCAL_ERROR — Error fiscal/lógico
301–307FISCAL_AUX — Mensajes auxiliares informativos
400–417FISCAL_INTERNAL — Errores internos del controlador

Consulta de descripción de error

desc = oErrors.GetErrorDesc(codigo)! Retorna descripción en español

FiscalErrors contiene un catálogo de más de 200 códigos de error clasificados en categorías: Sistema, E/S, Socket, XML, JSON, Criptografía, Imagen, POS, Auditoría, Memoria Fiscal, Aritmética, Base de Datos, Protocolo e Interfaz.


11. Logging (FiscalLog)

El sistema de logging registra todos los comandos enviados y respuestas recibidas.

Configuración

! Habilitar via variable de entorno (ZVar_GetAndSet)
ZVar_GetAndSet('Fiscal.Log',1)! 1 = activo, 0 = inactivo! O directamente via FiscalConfig:
oConfig.SetLogEnable(1)
oConfig.SetLogFilename('C:\Logs\fiscal')

Nombre del archivo de log

{ruta_base}_{serie}_{YYYY}_{MM}.log
Ejemplo: C:\Logs\fiscal_A12345678_2026_04.log

Formato de entrada

[2026-04-24 14:32:10] → {"AbrirComprobante":{...}}
[2026-04-24 14:32:11] ← {"AbrirComprobante":{"Secuencia":"12345",...}}

Uso programático (raramente necesario directamente)

oLog.Init(oConfig)
oLog.Write('Mensaje de texto plano')
oLog.Write(cstring_var)

Los comandos de FiscalCommand llaman a FiscalLog automáticamente en cada envío/respuesta.


12. Protocolo JSON

Formato de solicitud

{
"NombreComando": {
"Parametro1": "valor1",
"Parametro2": "valor2"
}
}

Formato de respuesta — Éxito

{
"NombreComando": {
"Secuencia": "12345",
"Estado": {
"Impresora": ["estado1", "estado2"],
"Fiscal": ["estadoFiscal1"]
},
"CamposEspecificos": "..."
}
}

Formato de respuesta — Controlador ocupado

{
"ControladorOcupado": {
"Secuencia": "12345",
"Estado": { ... }
}
}

Cuando el controlador responde ControladorOcupado, FiscalCommand entra en bucle de reintento automático. La frecuencia y cantidad de reintentos son configurables. Durante la espera, se invoca el callback MyNotifyClass que activa la animación de PulseBarClass.

Formato de respuesta — Error

{
"Error": {
"Identificador": "CODIGO_ERROR",
"Descripcion": "Descripción del error",
"Contexto": "Información adicional"
}
}

13. Flujo de trabajo completo

Ejemplo mínimo: Factura B

! 1. Crear y configurar el coordinador de conexión
oFiscal.SetPDF(idPuntDeVenta)
oFiscal.SetConnectionString(connStr)IF NOT oFiscal.Open()Message('Error al conectar con el controlador fiscal')RETURNEND! 2. Crear el orquestador
oOrch.Init('Emisión Factura B')! 3. Datos del receptor
oOrch.Cliente('20304050607','Juan Perez','Av. Corrientes 1234', IVA_Consumidor_Final)! 4. Tipo de comprobante
oOrch.Titulo(Doc_FacturaB,1,'')! 5. Ítems
oOrch.Item('Producto A',2,1500.00, IVA_Gravado,21.00,'001')
oOrch.Item('Producto B',1,800.50, IVA_Gravado,10.50,'002')! 6. Pago
oOrch.Pago(Pay_Efectivo,3800.50,'')! 7. Cerrar el comprobante
oOrch.Cierre()! 8. Ejecutar (muestra ventana de progreso)
oOrch.Run()

Ejemplo: Cierre Z diario

! Solo ejecutar si se confirmó con el operadorIFMessage('¿Confirma el Cierre Z?','Cierre Diario',BUTTON:YesNo)=BUTTON:Yes
oCierreZ.Init(oConfig)IF oCierreZ.Run()= FISCAL_OK
Message('Cierre Z N° '& oCierreZ.GetNroZ()&' realizado correctamente.')ELSEMessage('Error en Cierre Z: '& oCierreZ.GetLastError())ENDEND

Ejemplo: Auditoría por fecha

 oAudit.Init(oConfig)
oAudit.SetFechaDesde('20260101')
oAudit.SetFechaHasta('20260131')IF oAudit.Run()<> FISCAL_OK
Message('Error de auditoría: '& oAudit.GetLastError())END

14. Referencia de bases de datos

Tabla pdf_config

CampoTipoDescripción
id_pdfLONGIdentificador del punto de venta
ipSTRINGIP del controlador fiscal (ej: "192.168.1.50")

Tabla pdf_fiscales

CampoTipoDescripción
serieSTRINGNúmero de serie del controlador
prefijoSTRINGPrefijo del punto de venta (ej: "0001")
marcaLONG1=Epson, 2=Hasar, 9=Virtual
modeloLONGConstante Fiscal_Type (ver sección 9)
if_ncLONGFlag de notas de crédito

Consultas ejecutadas por FiscalClass

-- LoadIP()SELECT ip FROM pdf_config WHERE id_pdf = :pdf
-- LoadParams() (tras obtener serial del controlador)SELECT prefijo, marca, modelo, if_nc
FROM pdf_fiscales
WHERE serie = :serial

Versión

La constante FISCAL_VERSION (definida en FiscalTypes.inc) identifica la versión de la biblioteca.

Formato:YY.MM.DDX

ParteDescripciónEjemplo
YYAño (2 dígitos)26
MMMes (2 dígitos)04
DDDía (2 dígitos)25
XRevisión del día (letra: A, B, C…)A

Historial

VersiónCambios
26.04.25APrimera versión pública

Notas para el desarrollador

  • Nunca instanciar FiscalConfig directamente: es un singleton. Acceder siempre a través de su instancia global.
  • El Cierre Z es irreversible: validar siempre con el operador antes de ejecutarlo.
  • LibCurl debe estar en el PATH o en la carpeta del ejecutable: sin él, todos los comandos fallan con HTTP:CURL_ERROR.
  • El logging crea un archivo por mes: monitorear espacio en disco en instalaciones con alto volumen de comprobantes.
  • FiscalOrchestra.Run() es bloqueante: abre una ventana modal. Si se necesita integración en un proceso batch sin UI, ejecutar los comandos directamente vía sus clases concretas.
  • Reintentos por ControladorOcupado: el controlador puede estar procesando un trabajo anterior. FiscalCommand reintenta automáticamente; el desarrollador puede configurar el número de intentos y el delay entre ellos.

About

Hasar Fiscal Printer Driver

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages