Este es un codigo super antiguo que encontre, para impresoras fiscales BMC Camel. Quizás sirva para darte una idea.
* BMCCAMEL.PRG
* Manejo de la impresora BMC Camel
*
#DEFINE CRLF CHR(13)+CHR(10)
DEFINE CLASS bmccamel AS Plugin
Description = "Controlador para la impresora fiscal BMC Camel"
Hooks = "controladorImpresoraFiscal"
Puerto = "COM1"
lastErrorCode = 0
lastStatusCode = 0
DIMENSION errorCodes[1,1]
DIMENSION statusCodes[1,1]
PROCEDURE Init
*
* Se registra la interfaz del plugin
WITH pluginsHelper.Hooks
.Register("controladorImpresoraFiscal","","","Controlador para la impresora fiscal")
.Register("CIFVerificarDriver","","","Verificar si el driver requerido para la impresora esta presente")
.Register("CIFCargarDriver","","","Cargar el driver para la impresora fiscal")
.Register("CIFAbrirPuerto","","estatus,error","Abrir el puerto de la impresora fiscal")
.Register("CIFCerrarPuerto","","estatus,error","Cerrar el puerto de la impresora fiscal")
.Register("CIFReiniciarImpresora","","estatus,error","Reiniciar la impresora")
.Register("CIFCancelarTransaccion","","error,estatus","Cancelar la transaccion en proceso")
.Register("CIFEnviarComando","comando","estatus,error","Enviar un comando a la impresora fiscal")
.Register("CIFConsultarEstatus","","estatus,error","Consultar el estatus de la impresora")
.Register("CIFImpLineaCabezera","linea,data","estatus,error","Imprimir una linea de cabezera")
.Register("CIFImpLineaDetalle","codart,nomart,precio,cantidad,iva,dcto","estatus,error","Imprimir linea de detalle")
.Register("CIFImpLineaDevolucion","codart,nomart,precio,cantidad,iva,dcto","estatus,error","Imprimir linea de devolucion")
.Register("CIFImprimirSubtotal","","estatus,error","Imprimir el subtotal del documento")
.Register("CIFImprimirTotalFA","","estatus,error","Imprimir el total de la factura")
.Register("CIFImprimirTotalNC","","estatus,error","Imprimir el total de la NC")
.Register("CIFUltimaFactura","","numero,estatus,error","Ultimo numero de factura generado por la impresora")
.Register("CIFReporteX","","estatus,error","Emitir el reporte X")
.Register("CIFReporteY","","estatus,error","Emitir el reporte Y")
.Register("CIFReporteZ","","estatus,error","Emitir el reporte Z")
.Register("CIFFirmware","","estatus,error","Imprimir informacion del firmware")
.Register("CIFSerial","","serial,estatus,error","Obtener el serial de la impresora")
.Register("CIFImpLineaNF","data","estatus,error","Imprimir una linea en modo no fiscal")
.Register("CIFCerrarNF","data","estatus,error","Cerrar el modo no fiscal")
ENDWITH
* Se define la lista de codigos de estatus
DIMENSION THIS.statusCodes[13]
FOR i = 1 TO ALEN(THIS.statusCodes,1)
THIS.statusCodes[i] = "0x" + THIS.dec2HEx(i) + ": Sin información"
ENDFOR
THIS.statusCodes[ 1]="Estatus desconocido"
THIS.statusCodes[ 2]="En Modo Prueba y en Espera"
THIS.statusCodes[ 3]="En Modo Prueba y Emisión de Documentos Fiscales"
THIS.statusCodes[ 4]="En Modo Prueba y Emisión de Documentos No Fiscales"
THIS.statusCodes[ 5]="En Modo Fiscal y en Espera"
THIS.statusCodes[ 6]="En Modo Fiscal y Emisión de Documentos Fiscales"
THIS.statusCodes[ 7]="En Modo Fiscal y Emisión de Documentos No Fiscales"
THIS.statusCodes[ 8]="En Modo Fiscal y Cercana Carga Completa De La Memoria Fiscal Y en Espera"
THIS.statusCodes[ 9]="En Modo Fiscal y Cercana Carga Completa De La Memoria Fiscal Y en Emisión de Documentos Fiscales"
THIS.statusCodes[10]="En Modo Fiscal y Cercana Carga Completa De La Memoria Fiscal Y en Emisión de Documentos No Fiscales"
THIS.statusCodes[11]="En Modo Fiscal y Carga Completa De La Memoria Fiscal Y en Espera"
THIS.statusCodes[12]="En Modo Fiscal y Carga Completa De La Memoria Fiscal Y en Emisión de Documentos Fiscales"
THIS.statusCodes[13]="En Modo Fiscal y Carga Completa De La Memoria Fiscal Y en Emisión de Documentos No Fiscales"
THIS.statusCodes[0x0 + 1] = [Status Desconocido]
THIS.statusCodes[0x1 + 1] = [En modo Entrenamiento y en Espera]
THIS.statusCodes[0x2 + 1] = [En modo Entrenamiento Emitiendo Documento Fiscal]
THIS.statusCodes[0x3 + 1] = [En modo Entrenamiento Emitiendo Documento NO Fiscal]
THIS.statusCodes[0x4 + 1] = [En modo Fiscal y en Espera]
THIS.statusCodes[0x5 + 1] = [En modo Fiscal Emitiendo Documento Fiscal]
THIS.statusCodes[0x6 + 1] = [En modo Fiscal Emitiendo Documento NO Fiscal]
THIS.statusCodes[0x7 + 1] = [En modo Fiscal, Memoria Fiscal casi llena y en Espera]
THIS.statusCodes[0x8 + 1] = [En modo Fiscal, Memoria Fiscal casi llena y Emitiendo Documento Fiscal]
THIS.statusCodes[0x9 + 1] = [En modo Fiscal, Memoria Fiscal casi llena y Emitiendo Documento NO Fiscal]
THIS.statusCodes[0xA + 1] = [En modo Fiscal, Memoria Fiscal llena y en Espera]
THIS.statusCodes[0xB + 1] = [En modo Fiscal, Memoria Fiscal llena y Emitiendo Documento Fiscal]
THIS.statusCodes[0xC + 1] = [En modo Fiscal, Memoria Fiscal llena y Emitiendo Documento NO Fiscal]
* Se define la lista de codigos de error
DIMENSION THIS.errorCodes[0x99 + 1]
FOR i = 1 TO ALEN(THIS.errorCodes,1)
THIS.errorCodes[i] = "0x" + THIS.dec2HEx(i) + ": Sin información"
ENDFOR
THIS.errorCodes[0x00 + 1] = [OK]
THIS.errorCodes[0x01 + 1] = [Sin papel interno]
THIS.errorCodes[0x02 + 1] = [Error mecánico de la impresora]
THIS.errorCodes[0x03 + 1] = [Sin papel y error mecánico de la impresora]
THIS.errorCodes[0x50 + 1] = [Comando o valor inválido]
THIS.errorCodes[0x54 + 1] = [IVA inválido]
THIS.errorCodes[0x58 + 1] = [Cajero no asignado]
THIS.errorCodes[0x5C + 1] = [Sin papel]
THIS.errorCodes[0x60 + 1] = [Error fiscal]
THIS.errorCodes[0x64 + 1] = [Error en memoria fiscal]
THIS.errorCodes[0x6C + 1] = [Memoria fiscal llena]
THIS.errorCodes[0x70 + 1] = [Buffer lleno (debe enviar el comando RESTART)]
THIS.errorCodes[0x80 + 1] = [Error de comunicación]
THIS.errorCodes[0x89 + 1] = [Sin respuesta]
THIS.errorCodes[0x90 + 1] = [Error LRC]
THIS.errorCodes[0x91 + 1] = [Error interno del API]
THIS.errorCodes[0x99 + 1] = [Error abriendo archivo]
* Se verifica que se disponga del driver
THIS.CIFVerificarDriver()
* Se carga el driver
THIS.CIFCargarDriver()
*
ENDPROC
***********************************
**
** I M P L E M E N T A C I O N
**
***********************************
PROCEDURE CIFVerificarDriver(poParams)
*
LOCAL cFile
cFile = "TFHKAIF.DLL"
IF NOT FILE(cFile)
ThrowCustomEx("cifNoDriverException",cFile)
ENDIF
*
ENDPROC
PROCEDURE CIFCargarDriver(poParams)
DECLARE INTEGER OpenFpctrl IN c:\eposdp\TFHKAIF.DLL String lpPortName
DECLARE INTEGER CloseFpctrl IN c:\eposdp\TFHKAIF.DLL
DECLARE INTEGER CheckFprinter IN c:\eposdp\TFHKAIF.DLL
DECLARE INTEGER ReadFpStatus IN c:\eposdp\TFHKAIF.DLL LONG @lStatus ,LONG @lError
DECLARE INTEGER SendCmd IN c:\eposdp\TFHKAIF.DLL LONG @lStatus ,LONG @lError,STRING @cmd
DECLARE INTEGER SendNCmd IN c:\eposdp\TFHKAIF.DLL LONG @lStatus ,LONG @lError,STRING @bufferCmd
DECLARE INTEGER SendFileCmd IN c:\eposdp\TFHKAIF.DLL LONG @lStatus ,LONG @lError,STRING @fileCmd
DECLARE INTEGER UploadReportCmd IN c:\eposdp\TFHKAIF.DLL LONG @lStatus ,LONG @lError,STRING @cmd,string @fileCmd
DECLARE INTEGER UploadStatusCmd IN c:\eposdp\TFHKAIF.DLL LONG @lStatus ,LONG @lError,STRING @cmd,string @fileCmd
ENDPROC
PROCEDURE CIFAbrirPuerto(poParams)
*
LOCAL nResult
STORE "" TO THIS.OUT.Error,THIS.OUT.Estatus
nResult = OPENFPCTRL(THIS.Puerto)
IF nResult<>1
PRIVATE uError, uStatus
STORE 0 TO uError, uStatus
THIS.readPrinterStatus(@uStatus, @uError)
THIS.OUT.Estatus = THIS.getDescEstatus(uStatus)
THIS.OUT.Error = THIS.getDescError(uError)
ThrowCustomEx("cifAperturaPuertoException",THIS.getErrorEstatus(@uError, @uStatus))
RETURN False
ENDIF
*
ENDPROC
PROCEDURE CIFCerrarPuerto(poParams)
*
LOCAL nResult
STORE "" TO THIS.OUT.Error,THIS.OUT.Estatus
nResult = CLOSEFPCTRL()
IF nResult<>1
PRIVATE uError, uStatus
STORE 0 TO uError, uStatus
THIS.readPrinterStatus(@uStatus, @uError)
THIS.OUT.Estatus = THIS.getDescEstatus(uStatus)
THIS.OUT.Error = THIS.getDescError(uError)
ThrowCustomEx("cifCierrePuertoException",THIS.getErrorEstatus(@uError, @uStatus))
RETURN False
ENDIF
*
ENDPROC
PROCEDURE CIFReiniciarImpresora(poParams)
THIS.sendToPrinter("e", THIS.Params.OUT)
ENDPROC
PROCEDURE CIFCancelarTransaccion(poParams)
*
LOCAL lOk
lOk = True
STORE "" TO THIS.OUT.Error,THIS.OUT.Estatus
TRY
THIS.sendToPrinter("7", THIS.Params.OUT)
CATCH TO ex
lOk = False
ENDTRY
RETURN lOk
*
ENDPROC
PROCEDURE CIFEnviarComando(poParams)
THIS.sendToPrinter(poParams.comando, THIS.Params.OUT)
ENDPROC
PROCEDURE CIFImpLineaCabezera(poParams)
*
*-- Se validan los parametros
IF VARTYPE(poParams.linea)<>"N" OR NOT BETWEEN(poParams.linea,1,12)
ThrowCustomEx("cifLineaIncorrectaException",TRANSFORM(poParams.linea,""))
RETURN
ENDIF
IF VARTYPE(poParams.Data)<>"C"
ThrowCustomEx("cifParametroIncorrectoException","CIFImpLineaCabezera(DATA), linea #"+ALLTRIM(STR(poParams.linea))+" Data: "+TRANSFORM(poParams.data,""))
RETURN
ENDIF
*-- Se envia el comando
THIS.sendToPrinter("i" + PADL(poParams.linea,2,"0") + PADR(poPArams.data,40,SPACE(1)), THIS.Params.OUT)
*
ENDPROC
PROCEDURE CIFImpLineaDetalle(poParams, plDevolucion)
*
*-- Se valida los parametros
IF VARTYPE(poParams.CodArt)<>"C"
ThrowCustomEx("cifParametroIncorrectoException","CIFImprimirLineaDetalle(codart)")
RETURN False
ENDIF
IF VARTYPE(poParams.NomArt)<>"C"
ThrowCustomEx("cifParametroIncorrectoException","CIFImprimirLineaDetalle(nomart)")
RETURN False
ENDIF
IF VARTYPE(poParams.Precio)<>"N"
ThrowCustomEx("cifParametroIncorrectoException","CIFImprimirLineaDetalle(precio)")
RETURN False
ENDIF
IF VARTYPE(poParams.Cantidad)<>"N"
ThrowCustomEx("cifParametroIncorrectoException","CIFImprimirLineaDetalle(cantidad)")
RETURN False
ENDIF
IF VARTYPE(poParams.IVA)<>"C"
ThrowCustomEx("cifParametroIncorrectoException","CIFImprimirLineaDetalle(IVA)")
RETURN False
ENDIF
IF VARTYPE(poParams.DCTO)<>"N"
ThrowCustomEx("cifParametroIncorrectoException","CIFImprimirLineaDetalle(Dcto)")
RETURN False
ENDIF
IF !plDevolucion AND False
*
*-- Se envia el codigo de articulo
THIS.sendToPrinter("@" + poParams.codArt, THIS.PArams.OUT)
*-- Se envia el nombre, divido en dos strings de 20
THIS.sendToPrinter("@" + LEFT(poParams.nomArt,20), THIS.Params.OUT)
IF LEN(RTRIM(poParams.nomArt)) > 20
THIS.sendToPrinter("@" + SUBSTR(poParams.nomArt,21,20), THIS.Params.OUT)
ENDIF
*
ENDIF
*-- Se prepara el comando para el resto de los datos del item
LOCAL cComando
cComando = IIF(plDevolucion,"d","") + CHRTRAN(poParams.IVA,[ ABCD],[ !"#$]) + CHRTRAN(PADL(poParams.Precio,11,"0"),".","")
SET DECIMALS TO 3
cComando = cComando + STRTRAN(STRTRAN(STR(poParams.Cantidad,9,3),SPACE(1),'0'),'.')
SET DECIMALS TO 2
IF plDevolucion Or True
cComando = cComando + PADR(RTRIM(poParams.codArt)+" "+poParams.NomArt,40)
ELSE
cComando = cComando + PADR(".",40)
ENDIF
*-- Se envia el comando
THIS.sendToPrinter(cComando,THIS.Params.OUT)
*-- Si se indico un descuento, se envia
IF poPArams.Dcto > 0
cComando = [p-] + STRTRAN(STRTRAN(STR(poParams.Dcto,6,2),SPACE(1),'0'),'.')
THIS.sendToPrinter(cComando,THIS.Params.OUT)
ENDIF
*
ENDPROC
PROCEDURE CIFImpLineaDevolucion(poParams)
THIS.CIFImpLineaDetalle(poParams,True)
ENDPROC
PROCEDURE CIFImprimirSubTotal(poParams)
THIS.sendToPrinter([3],THIS.Params.OUT)
ENDPROC
PROCEDURE CIFImprimirTotalFA(poParams)
THIS.sendToPrinter([101],THIS.Params.OUT)
ENDPROC
PROCEDURE CIFImprimirTotalNC(poParams)
THIS.sendToPrinter([f01000000000000],THIS.Params.OUT)
ENDPROC
PROCEDURE CIFConsultarEstatus(poParams)
PRIVATE nStatus,nERror
STORE 0 TO nStatus, nError
STORE "" TO THIS.OUT.Error,THIS.OUT.Estatus
IF WST.Name<>"VES"
THIS.readPrinterStatus(@nStatus, @nError)
ELSE
nStatus = 0
nError = 0
ENDIF
THIS.OUT.estatus = THIS.getDescEstatus(nstatus)
THIS.OUT.error = THIS.getDescError(nerror)
RETURN nStatus
ENDPROC
PROCEDURE CIFUltimaFactura(poParams)
LOCAL cNumDoc,nPos
cNumDoc = "00000000"
*RETURN PADL(SECONDS(),9,"0") && SOLO mientras duran las pruebas
TRY
nPos = 1
THIS.CIFAbrirPuerto()
nPos = 2
cNumDoc = NVL(THIS.readS1("NUMULTFAC"),"")
nPos = 3
THIS.CIFCerrarPuerto()
CATCH TO ex
cNumDoc = ex.Message + " (" + STR(nPos)+")"
msgHelper.Warning("Error",cNumDoc)
cNumdoc = foox
ENDTRY
RETURN cNumDoc
ENDPROC
PROCEDURE CIFReporteX(poParams)
*
*-- Se abre el puerto
THIS.CIFAbrirPuerto()
*-- Se emite el reporte X
THIS.sendToPrinter("I0X",THIS.OUT)
doPause(5) && La pausa es necesaria para permitir que se cargue el archivo completamente
*-- Se descarga el reporte a un archivo temporal
LOCAL cTempFile,cBuff
cTempFile = getTempFile("PTF")
cBuff = FILETOSTR(cTempFile)
ERASE (cTempFile)
*-- Se obtiene el valor de "CAJERO" en el informe y se incrementa en 1
LOCAL cCajero
cCajero=SUBST(cbuff,AT('S1',cBuff)+2,2)
cCajero=PADL(INT(VAL(cCajero)) + 1,5,"0")
THIS.sendToPrinter("5" + cCajero, THIS.PArams.OUT)
*-- Se cierra el puerto
THIS.CIFCerrarPuerto()
*
ENDPROC
PROCEDURE CIFReporteY(poParams)
THIS.CIFReporteZ(poParams)
ENDPROC
PROCEDURE CIFReporteZ(poParams)
*
DOEVENTS
*-- Se abre el puerto
THIS.CIFAbrirPuerto()
*-- Se emite el reporte Z
THIS.sendToPrinter("I0Z",THIS.OUT)
*-- Se restablece el contador de cajeros
THIS.sendToPrinter("6",THIS.OUT)
LOCAL nLastStatusCode, nLastErrorCode
nLastStatusCode = THIS.lastStatusCode
nLastErrorCode = THIS.lastErrorCode
*-- Se actualiza la informacion del reporte en EM
IF INLIST(nLastStatusCode,0,4) AND nLastErrorCode = 0
THIS.actualizarTablaZ()
ELSE
AUD.addEntry("No se actualizo historicoZ. LastStatusCode={0}, LastErrorCode={1}","CIF","REPORTEZ",AUD.Severity.Critical,nLastStatusCode,nLastErrorCode)
ENDIF
*-- Se actualiza la fecha del ultimo reporte Z para la estacion
dictHelper.addEntry("POS.FiscalPrinter.{WST.Name}.FechaUltimoReporteZ",DATE())
*-- Se cierra el puerto
THIS.CIFCerrarPuerto()
*
ENDPROC
PROCEDURE CIFFirmware(poParams)
THIS.CIFAbrirPuerto()
THIS.sendToPrinter("x",THIS.OUT)
THIS.CIFCerrarPuerto()
ENDPROC
PROCEDURE CIFSerial(poParams)
LOCAL cSerial
cSerial = "000000"
TRY
THIS.CIFAbrirPuerto()
cSerial = NVL(THIS.readS1("SERIAL"),"")
THIS.CIFCerrarPuerto()
CATCH
ENDTRY
RETURN cSerial
ENDPROC
PROCEDURE CIFImpLineaNF(poParams)
*
*-- Se validan los parametros
IF VARTYPE(poParams.Data)<>"C"
ThrowCustomEx("cifParametroIncorrectoException","CIFImpLineaNF(DATA), linea #"+ALLTRIM(STR(poParams.linea))+" Data: "+TRANSFORM(poParams.data,""))
RETURN
ENDIF
*-- Se envia el comando
THIS.sendToPrinter([800] + LEFT(poPArams.data,35), THIS.Params.OUT)
*
ENDPROC
PROCEDURE CIFCerrarNF(poParams)
THIS.sendToPrinter([810]+LEFT(NVL(poParams.data,SPACE(35)),35),THIS.Params.OUT)
ENDPROC
*************************************
** METODOS DE SOPORTE
*************************************
PROCEDURE sendToPrinter(pcComando, poOUT)
*
PRIVATE uStatus,uError,nResult
STORE 0 TO uStatus,uError
IF TYPE("THIS.PArams.OUT.Error")<>"U"
STORE "" TO THIS.Params.OUT.Error,THIS.Params.OUT.Estatus
ENDIF
poOUT.Error = ""
poOUT.Estatus = ""
nResult = SENDCMD(@uStatus,@uError,pcComando)
IF nResult <> 1
THIS.lastErrorCode = uError
THIS.lastStatusCode = uStatus
poOUT.Error = THIS.getDescError(uError)
poOUT.Estatus = THIS.getDescEstatus(uStatus)
ThrowCustomEx("cifGeneralException",THIS.getErrorEstatus(uError,uStatus,pcComando))
RETURN False
ENDIF
*
ENDPROC
PROCEDURE downloadFromPrinter(pcComando, pcOutFile, poOut)
*
PRIVATE uStatus,uError,nResult
STORE 0 TO uStatus,uError
IF TYPE("THIS.PArams.OUT.Error")<>"U"
STORE "" TO THIS.Params.OUT.Error,THIS.Params.OUT.Estatus
ENDIF
poOUT.Error = ""
poOUT.Estatus = ""
nResult = UPLOADREPORTCMD(@uStatus,@uError,pcComando,pcOutFile)
IF nResult <> 1
THIS.lastErrorCode = uError
THIS.lastStatusCode = uStatus
poOUT.Error = THIS.getDescError(uError)
poOUT.Estatus = THIS.getDescEstatus(uStatus)
ThrowCustomEx("cifGeneralException",THIS.getErrorEstatus(uError,uStatus,pcComando))
RETURN False
ENDIF
*
ENDPROC
PROCEDURE getDescError(pnError)
RETURN THIS.errorCodes[pnError + 1]
ENDPROC
PROCEDURE getDescEstatus(pnEstatus)
RETURN THIS.statusCodes[pnEstatus + 1]
ENDPROC
PROCEDURE getErrorEstatus(pnError, pnEstatus, pcComando)
RETURN "Error : " + THIS.getDescError(pnError) + CRLF + ;
"Estatus: " + THIS.getDescEstatus(pnEstatus) + CRLF + ;
IIF(VARTYPE(pcComando)="C","Comando: "+pcComando,"")
ENDPROC
PROCEDURE readPrinterStatus(pnStatus, pnError)
LOCAL nREsult
nResult=READFPSTATUS(@pnStatus, @pnError)
IF nREsult<>1
ThrowCustomEx("cifStatusImpresoraException",THIS.getDescError(pnError))
RETURN False
ENDIF
ENDPROC
PROCEDURE readS1(pcClave)
*
*-- Se obtiene el estado S1 de la impresora
PRIVATE nResult,nError,nStatus,cBuff,uValor
STORE 0 TO nResult,nError,nStatus
STORE "" TO cBuff
STORE NULL TO uValor
IF WST.NAme <> "VES"
PRIVATE cTmpFile,cCommand
cTmpFile = CONFIG.Folders.Temp + "\" + WST.Name + "_S1.TMP"
cCommand = "S1"
nResult = UPLOADSTATUSCMD(@nStatus,@nError,cCommand,cTmpFile)
IF nResult = 1
COPY FILE (cTmpFile) TO ("C:\EPOSDP\SALIDA.TXT")
cBuff = FILETOSTR(cTmpFile)
ERASE (cTmpFile)
ENDIF
ELSE
cBuff = SPACE(2) + "foo" + CHR(10) + "foo" + CHR(10) + TRANSFORM(SECONDS(),"@L 9999999")
nResult = 1
ENDIF
IF nResult<>1
msgHelper.Notify("Test","Error="+STR(nError)+" Status: "+STR(nStatus))
ThrowCustomEx("cifGeneralException",THIS.getErrorEstatus(nError,nStatus))
RETURN NULL
ENDIF
cBuff = SUBSTR(cBuff,3)
cBuff = SUBS(cBuff,1,2) + CHR(10) + ;
SUBS(cBuff,3,17) + CHR(10) + ;
SUBS(cBuff,20,8) + CHR(10) + ;
SUBS(cBuff,28,5) + CHR(10) + ;
SUBS(cBuff,33,8) + CHR(10) + ;
SUBS(cBuff,41,5) + CHR(10) + ;
SUBS(cBuff,46,4) + CHR(10) + ;
SUBS(cBuff,50,4) + CHR(10) + ;
SUBS(cBuff,54,11) + CHR(10) + ;
SUBS(cBuff,65,10) + CHR(10) + ;
SUBS(cBuff,75,6) + CHR(10) + ;
SUBS(cBuff,81,6) + CHR(10)
STRTOFILE(CHRT(cBuff,CHR(10),"-"),"C:\TEMP\BUFF.TXT")
DO CASE
**\/** Número de Cajero
CASE pcClave=[CAJERO]
uValor=GETWORDNUM(cBuff,1,CHR(10))
**\/** Ventas del Dia
CASE pcClave=[VENTAS]
uValor=GETWORDNUM(cBuff,2,CHR(10))
uValor=VAL(uValor)/100
**\/** Número de la última factura
CASE pcClave=[NUMULTFAC]
uValor=GETWORDNUM(cBuff,3,CHR(10))
**\** Cantidad de Facturas del Día
CASE pcClave=[CANTFACDIA]
uValor=GETWORDNUM(cBuff,4,CHR(10))
uValor=VAL(uValor)
**\/** Número del Documento No Fiscal
CASE pcClave=[NUMDOCNOFIS]
uValor=GETWORDNUM(cBuff,5,CHR(10))
**\/** Cantidad de Documentos No Fiscales
CASE pcClave=[CANTDOCNOFIS]
uValor=GETWORDNUM(cBuff,6,CHR(10))
uValor=VAL(uValor)
**\/** Contador de Cierres Diarios
CASE pcClave=[CANTCIERREZ]
uValor=GETWORDNUM(cBuff,7,CHR(10))
uValor=VAL(uValor)
**\/** Contador de Reportes de Auditoria
CASE pcClave=[CONTREPAUD]
uValor=GETWORDNUM(cBuff,8,CHR(10))
**\/** Nro de RIF
CASE pcClave=[RIF]
uValor=GETWORDNUM(cBuff,9,CHR(10))
**\/** Serial de la Impresora
CASE pcClave=[SERIAL]
uValor=GETWORDNUM(cBuff,10,CHR(10))
**\/** Hora actual de la impresora
CASE pcClave=[HORAACT]
uValor=GETWORDNUM(cBuff,11,CHR(10))
**\/** Fecha actual de la impresora
CASE pcClave=[FECHAACT]
uValor=GETWORDNUM(cBuff,12,CHR(10))
uValor=SUBST(uValor,1,2) + [-] + SUBST(uValor,3,2) + [-] + SUBST(uValor,5,2)
uValor=CTOD(uValor)
ENDCASE
RETURN uValor
*
ENDPROC
PROCEDURE dec2Hex(nDecimal)
LOCAL lcHexa, lcChr, lnResto
lcHexa=''
DO WHILE nDecimal > 0
lnResto = MOD(nDecimal,16)
nDecimal = INT(nDecimal / 16)
lcChr = IIF(lnResto < 10,STR(lnResto,1),CHR(lnResto + 55))
lcHexa = lcChr + lcHexa
ENDDO
RETURN lcHexa
ENDPROC
PROCEDURE actualizarTablaZ(pcDateRange, pcSerial, pcBuff)
*
LOCAL cToday
SET CENTURY OFF
cToday = CHRT(DTOC(DATE()),"-/.","")
SET CENTURY ON
IF VARTYPE(pcDateRange)<>"C"
pcDateRange=cToday + cToday
ENDIF
*-- Se descarga la informacion de los reportes Z emitidos durante el dia actual
LOCAL cBuff
IF EMPTY(pcBuff)
LOCAL cTempFile,cBAKFile,cCmd
cTempFile = getTempFile("PTF")
cBAKFile = ADDBS(CONFIG.Folders.Temp) + "REPZ_"+cToday+".TXT"
cCmd = "U2A" + pcDateRange
THIS.downloadFromPrinter(cCmd, cTempFile, THIS.Params.OUT)
doPause(5)
cBuff = FILETOSTR(cTempFile)
COPY FILE (cTempFile) TO (cBAKFile)
ERASE (cTempFile)
ELSE
cBuff = pcBuff
ENDIF
*-- Se separa el contenido del archivo en lineas, donde cada linea corresponde a los datos
* de un reporte Z particular
*
LOCAL ARRAY aZReports[1]
LOCAL nZReportCount,nZReport
nZReportCount = ALINES(aZReports,cBuff)
LOCAL cNumero,tFecha,cNumUltFac,tFecUltFac,nVentasEx,nVentas1,nIVA1,nVentas2,nIVA2,nVentas3,nIVA3,nDevEx,nDev1,nIVADev1,nDev2,nIVADev2,nDev3,nIVADev3,cNumUltDev
LOCAL oReporteZ,oSP
oReporteZ = CreateBuffer("hizSerialIF,hizNumeroReporte,hizFecha,hizNumUltFac,hizFecUltFac,"+;
"hizVentasEx,hizVentas1,hizIVA1,hizVentas2,hizIVA2,hizVentas3,hizIVA3,"+;
"hizDevEx,hizDev1,hizIVADev1,hizDev2,hizIVADev2,hizDev3,hizIVADev3,hizNumUltDev")
oSP = newSP("spUpdHistoricoZ")
FOR nZReport = 1 TO nZReportCount
*
STORE "" TO cNumero,cNumUltFac,cNumUltDev
STORE 0.0 TO nVentasEx,nVentas1,nIVA1,nVentas2,nIVA2,nVentas3,nIVA3,nDevEx,nDev1,nIVADev1,nDev2,nIVADev2,nDev3,nIVADev3
STORE {//::} TO tFecha,tFecUltFac
cBuff = aZReports[nZReport]
IF LEFT(cBuff,4)='S101' OR AT(" ",cbuff) = 0
EXIT
ENDIF
*-- Se extraen los datos del reporte Z
SET DATE DMY
WITH oReporteZ
.hizSerialIF = EVL(pcSerial,POSCONF.Local.SerialIF)
.hizNumeroReporte = SUBSTR(cBuff,1,4)
.hizFecha = DTOT(CTOD(TRANSFORM(SUBSTR(cBuff,5,6),"@R 99-99-2099")))
.hizFecUltFac = .hizFecha
.hizVentas1 = VAL(SUBSTR(cBuff,16,13)) / 100
.hizVentas2 = VAL(SUBSTR(cBuff,30,13)) / 100
.hizVentas3 = VAL(SUBSTR(cBuff,44,13)) / 100
.hizVentasEx = VAL(SUBSTR(cBuff,58,13)) / 100
.hizIVA1 = VAL(SUBSTR(cBuff,72,13)) / 100
.hizIVA2 = VAL(SUBSTR(cBuff,86,13)) / 100
.hizIVA3 = VAL(SUBSTR(cBuff,100,13)) / 100
.hizDev1 = VAL(SUBSTR(cBuff,114,13)) / 100
.hizDev2 = VAL(SUBSTR(cBuff,128,13)) / 100
.hizDev3 = VAL(SUBSTR(cBuff,142,13)) / 100
.hizDevEx = VAL(SUBSTR(cBuff,156,13)) / 100
.hizIVADev1 = VAL(SUBSTR(cBuff,170,13)) / 100
.hizIVADev2 = VAL(SUBSTR(cBuff,184,13)) / 100
.hizIVADev3 = VAL(SUBSTR(cBuff,198,13)) / 100
.hizNumUltFac = SUBSTR(cBuff,211,8)
.hizNumUltDev = SUBSTR(cBuff,219,8)
ENDWITH
SET DATE ITALIAN
*-- Se registran/actualizan los datos del reporte Z en el historico
oSP.importParams(oReporteZ)
oSP.Params.usrId = Usuario.usrId
oSP.ExecuteNonQuery()
*-- Se analiza el siguiente reporte en la lista
*
ENDFOR
*
ENDPROC
ENDDEFINE
***************************************************
**
** E X C E P C I O N E S
**
***************************************************
DEFINE CLASS cifGeneralException AS baseException
Message = "Ocurrió un error al intentar enviar un comando a la impresora fiscal"
ENDDEFINE
DEFINE CLASS cifLineaIncorrectaException AS baseException
Message = "El nro. de linea indicado es incorrecto"
ENDDEFINE
DEFINE CLASS cifParametroIncorrectoException AS baseException
Message = "El parametro es incorrecto o no se indicó"
ENDDEFINE
DEFINE CLASS cifAperturaPuertoException AS baseException
Message = "Ocurrió un error al intentar abrir el puerto de la impresora"
ENDDEFINE
DEFINE CLASS cifStatusImpresoraException AS baseException
Message = "Ocurrio un error al intentar leer el estado de la impresora"
ENDDEFINE
DEFINE CLASS cifCierrePuertoException AS baseException
Message = "Ocurrió un error al intentar cerrar el puerto de la impresora"
ENDDEFINE
DEFINE CLASS cifNoDriveException AS baseException
Message = "No se encontró la libreria DLL para la comunicación con la impresora fiscal"
ENDDEFINE
****************************************** FIN DEL DOCUMENTO *********************************************************
* FACTURAVENTA.PRG
* Plugin para manejar la impresion de una factura de venta
*
DEFINE CLASS facturaVenta AS Plugin
*
Description = "Imprimir una factura de venta"
hooks = "imprimirFacturaVenta"
PROCEDURE onInvoke(pcHook,poParams)
*
*-- Se obtienen los datos del ticket
PRIVATE sp,oTicket
sp = newSP("spSMGetTicketInfoById")
sp.Params.tckId = poParams.tckId
oTicket = sp.executeRow()
*-- Se obtiene una referencia al driver de la impresora
LOCAL oIF
oIF = pluginsHelper.getPlugin("controladorImpresoraFiscal")
IF ISNULL(oIF)
ThrowCustomEx("fvNoCIFException")
RETURN
ENDIF
*-- Se cierra el puerto (por si quedo abierto)
TRY
oIF.Invoke("CIFCerrarPuerto")
CATCH
ENDTRY
*-- Se inicia un ciclo para permitir repetir la impresion en caso
* que ocurriera un error durante el proceso
*
LOCAL lOk,lRetry
lOk = False
lRetry = False
DO WHILE True
*
TRY
*-- Se abre el puerto de la impresora
oIF.Invoke("CIFAbrirPuerto")
*-- Se genera la cabezera de la factura
IF NOT lRetry
oIF.Invoke("CIFReiniciarImpresora")
ENDIF
oIF.Invoke("CIFImpLineaCabezera",1,'Doc.: '+oTicket.tckNumFacBO)
oIF.Invoke("CIFImpLineaCabezera",2,RTRIM(Usuario.usrNombre)+" "+WST.Name)
oIF.Invoke("CIFImpLineaCabezera",3,'CI/RIF : '+oTicket.cliCedRIF)
oIF.Invoke("CIFImpLineaCabezera",4,'Cliente: '+oTicket.cliNombre)
oIF.Invoke("CIFImpLineaCabezera",5,'Telf. : '+oTicket.cliTelefono)
oIF.Invoke("CIFImpLineaCabezera",6,'Direc. : '+LEFT(oTicket.cliDireccion,40))
oIF.Invoke("CIFImpLineaCabezera",7,SUBSTR(oTicket.cliDireccion,41))
*-- Se obtiene el detalle de la factura
sp = newSP("spSMListTicketById")
sp.Params.tckId = poParams.tckId
sp.Execute("QITEMS")
SELECT QITEMS
SCAN
IF comTipo = "01"
oIF.Invoke("CIFImpLineaDetalle",comPLU,comTexto,comPrecio,comCant,comIVA,comPctDcto)
ENDIF
IF comTipo = "03"
oIF.Invoke("CIFImpLineaDevolucion",comPLU,comTexto,comPrecio,comCant,comIVA,comPctDcto)
ENDIF
ENDSCAN
USE IN QITEMS
*-- Se imprime el subtotal y el total
oIF.Invoke("CIFImprimirSubTotal")
oIF.Invoke("CIFImprimirTotalFA")
*-- Se imprime el ticket de promocion (si esta definido)
THIS.imprimirPromocion(oIF)
lOk = True
CATCH TO ex
lOk = False
lRetry = True
ex = getInnerEx(ex)
IF LEFT(LOWER(ex.class),3) == "cif"
LOCAL cResponse
cResponse = ""
IF INLIST(oIF.lastErrorCode,0x5C,0x01)
cResponse = msgHelper.Custom("Error de impresion",;
"Falta papel en la impresora. Por favor reponga el papel, reinicie la impresora y pulse el botón REIMPRIMIR...",;
"Reimprimir,Cancelar","REPRINT,CANCEL",;
"IMG\PrinterError.PNG",TSGUI.panelColorStyles.Normal)
ELSE
cResponse = msgHelper.Custom("Error de impresion",;
"Ocurrió el siguiente error durante el proceso de impresión:\n\n"+;
ex.Message + "\n\n" + ;
"Estatus: " + oIF.OUT.Estatus + "\n"+;
"Condición: " + oIF.OUT.Error,;
"Reimprimir,Cancelar","REPRINT,CANCEL",;
"IMG\ErrorIcon.PNG",TSGUI.panelColorStyles.Critical)
ENDIF
IF cResponse = "CANCEL"
lRetry = False
ENDIF
ELSE
THROW
ENDIF
ENDTRY
IF lOk OR (NOT lRetry)
EXIT
ENDIF
TRY
oIF.Invoke("CIFReiniciarImpresora")
oIF.Invoke("CIFCancelarTransaccion")
CATCH
ENDTRY
TRY
oIF.Invoke("CIFCerrarPuerto")
CATCH
ENDTRY
*
ENDDO
TRY
oIF.Invoke("CIFCerrarPuerto")
CATCH
ENDTRY
THIS.OUT.OK = lOk
*-- Se obtiene el nro. de control asignado
IF lOk
THIS.OUT.numcontrol = oIF.Invoke("CIFUltimaFactura")
ENDIF
*
ENDPROC
PROCEDURE imprimirPromocion(poIF)
*
IF NOT FILE("PROMOCION.TXT")
RETURN
ENDIF
PRIVATE cBuff,oIF
cBuff = FILETOSTR("PROMOCION.TXT")
oIF = poIF
*-- Se imprime el contenido del archivo
LOCAL ARRAY aTicket[1]
LOCAL nCount, i, cLine
nCount = ALINES(aTicket,cBuff)
FOR i = 1 TO nCount
cLine = Expand(aTicket[i])
oIF.Invoke("CIFImpLineaNF",cLine)
ENDFOR
oIF.Invoke("CIFCerrarNF",SPACE(35))
*
ENDPROC
*
ENDDEFINE
DEFINE CLASS fvNoCIFException AS baseException
MEssage = "No se encontró una controladora para impresora fiscal instalada"
ENDDEFINE
****************************************** FIN DEL DOCUMENTO *********************************************************
Espero te sirva
Victor Espina