Page 1 of 1
Ayuda Numeracion de Facturas en Red
Posted: Sun Jul 08, 2007 2:07 am
by Databaselab2002
Estimados Colegas
Tengo un aplicacion en servidor a la que accedo via acceso directo desde otras terminales, El numero de factura lo tomo de un dbf, el problema
que estoy teniendo es que cuando acceden dos terminales al mismo
tiempo les asigna el mismo numero , Lo que quiero hacer es que le asigne
otro numero o mantener en espera al otro usuario , alguien me puede orientar como solucionarlo
Gracias
Fabian
Databaselab2002@yahoo.com.ar
SELE 15
USE CONTRATO shared
STORE CONTRATO->NTICKET TO XNCON
NT=0
STORE NTICKET TO NT
XNCON=XNCON+1
if rlock()
REPLACE CONTRATO->NTICKET WITH XNCON
else
alert("Archivo Bloqueado por otro usuario",,"Red")
endif
Posted: Sun Jul 08, 2007 3:15 am
by Francisco Horta
fabian,
lo que yo te puedo recomendar es asignar el numero de factura hasta el momento de grabar la factura, si quieres saber que numero le toco de factura muestraselo en una ventana y listo !!,
salu2
paco
Re: Ayuda Numeracion de Facturas en Red
Posted: Sun Jul 08, 2007 11:07 am
by FiveWiDi
Si cuando accedes a la DBF que contiene el número de factura le sumas 1, seguidamente debes realizar un DBCommit() para que en el resto de puestos que acceden por red vean que se ha incrementado en 1 ese valor.
Recuerda, en red si no realizas un DBCommit() cuando alteras el valor de _ de la dBF, el resto de puestos de la red no ven _.
Y en los puestos que estan 'mirando' la pantalla debe existir la posibilidad de realizar un Goto( Recno() ) para que se refresquen los valores que estan 'mirando'.
Además yo haría lo siguiente aun sin saber para que sirven XNCON ni NT:
SELE 15
USE CONTRATO shared
if rlock()
NTICKET = NTICKET + 1
XNCON = NTICKET
DBCommit()
DBUnlock()
NT=0
NT = NTICKET
else
alert("Archivo Bloqueado por otro usuario",,"Red")
endif
Saludos
Carlos G.
Databaselab2002 wrote:Estimados Colegas
Tengo un aplicacion en servidor a la que accedo via acceso directo desde otras terminales, El numero de factura lo tomo de un dbf, el problema
que estoy teniendo es que cuando acceden dos terminales al mismo
tiempo les asigna el mismo numero , Lo que quiero hacer es que le asigne
otro numero o mantener en espera al otro usuario , alguien me puede orientar como solucionarlo
Gracias
Fabian
Databaselab2002@yahoo.com.ar
SELE 15
USE CONTRATO shared
STORE CONTRATO->NTICKET TO XNCON
NT=0
STORE NTICKET TO NT
XNCON=XNCON+1
if rlock()
REPLACE CONTRATO->NTICKET WITH XNCON
else
alert("Archivo Bloqueado por otro usuario",,"Red")
endif
Posted: Sun Jul 08, 2007 3:14 pm
by jllinas
Hola,
Tal y como explica Francisco, los numeradores de documentos en cualquier sistema deben utilizarse cuando terminaste de capturar la factura, o sea, al final.
Si deseas algo "bonito", puedes mostrarlo desde el principio en la ventana de la factura, pero SIEMPRE antes de grabar la factura, debes verificar que no estas generando el mismo numero que ya fue utilizado por otra factura.
Asumí que estas utilizando DBCOMMIT(), así que de otra manera todo esto no funciona.
Suerte...
Posted: Sun Jul 08, 2007 3:46 pm
by R.F.
Asi es, los numeros consecutivos de documentos se asignan AL FINAL, una vez que hayas terminado la captura, bloqueas los archivos, asignas el numero consecutivo, guardas la informacion y le avisas al usuario:
Se captuardo la factura No. TAL
y listo
Re: Ayuda Numeracion de Facturas en Red
Posted: Mon Jul 09, 2007 5:06 am
by lubin
Hola Fabian
La idea es que cuando uno de los usuarios acceda al Registtro Contador donde controlas el nro de la factura, lo bloqueas temporalmente, generas el nuevo numero ..haces el N+1 y lo grabas en tu factura (al comienzo) y luego desbloqueas el registro contador para que el otro usuario acceda, el oro usuario lo mantienes en un "Wait" o "En Espera" que creo que es lo que te falta.. lo pones en un Do While... Enddo hasta que se libere el registro... .. normamente es inmediato...
ojala te ayude..
Lubin
Databaselab2002 wrote:Estimados Colegas
Tengo un aplicacion en servidor a la que accedo via acceso directo desde otras terminales, El numero de factura lo tomo de un dbf, el problema
que estoy teniendo es que cuando acceden dos terminales al mismo
tiempo les asigna el mismo numero , Lo que quiero hacer es que le asigne
otro numero o mantener en espera al otro usuario , alguien me puede orientar como solucionarlo
Gracias
Fabian
Databaselab2002@yahoo.com.ar
SELE 15
USE CONTRATO shared
STORE CONTRATO->NTICKET TO XNCON
NT=0
STORE NTICKET TO NT
XNCON=XNCON+1
if rlock()
REPLACE CONTRATO->NTICKET WITH XNCON
else
alert("Archivo Bloqueado por otro usuario",,"Red")
endif
Posted: Mon Jul 09, 2007 8:27 am
by pymsoft
Fabian,
Puedes usar un archivo de contadores y abrirlo en modo esclusivo, tomar el numero aumentarle 1, salvarlo y cerrar el archivo.
Si no puedes abrir el archivo de contadores (quiere decir que alguien esta aumentando los contadores), reintentas varias veces.
Es inmediato, aunque esten trabajando varios terminales haciendo facturas.
Saludos.
Posted: Mon Jul 09, 2007 10:39 am
by jose_murugosa
La soluciòn propuesta es correcta, si tu grabas el correlativo primero, y luego cancelas la factura (no la haces), el correlativo ya se grabò y el usuario siguiente obtuvo uno superior salteandose el previo.
La mejor soluciòn como todos han dicho es grabar al final, puedes leer el archivo de correlativo en forma compartida y mostrar un correlativo (el disponible) luego en el momento de grabar ver si se ha modificado y modificar el correlativo al ùltimo AL FINAL y corregir la vista en pantalla o no desplegar el correlativo y hacerlo al final luego de grabado.
Sea como sea, que muestres el correlativo al final o al principio y luego lo actualices el correlativo SIEMPRE serà el que estè disponible al momento de grabar, y por lo tanto se guarda al final.
PROCEDIMIENTO:
1)Ingreso los datos de la factura
2)Al guardar la factura:
a) abro el correlativo en forma exclusiva
b) tomo el correlativo correspondiente
c) incremento el correlativo
d) cierro la base dejàndola disponible para otro usuario
e)grabo la factura con el correlativo obtenido
f)regreso a ingreso de facturas
Como se dijo, la rutina de toma de correlativo deberà intentar abrir el correlativo hasta que tenga èxito (previendo que otro usuario de la red estè en ese momento grabando su correlativo).
ej.
DO WHILE .T.
USE CORRELAT EXCLUSIVE
IF .NOT. NETERR()
EXIT
ENDIF
ENDDO
.....
(o cualquier cosa parecida)
Posted: Mon Jul 09, 2007 2:37 pm
by R.F.
Efectivamente, las soluciones de bloqueos durante la captura no son eficientes, por una simple y sencilla razon:
El usuario se puede marchar (pasa muuuuy frecuentemente) y dejar bloqueado los archivos, me ha pasado que hay gente que deja todo el fin de semana corriendo un programa con las tablas bloqueadas.
Tampoco es valido asignar el numero antes porque si el usuario cancela la captura, pues ese numero ya se calculo y los siguientes usuarios tiene ya un numero desplazado.
Otra forma mas inteligente aún de hacerlo, es darle el numero manualmente, si, leyeron bien, manualmente, de acuerdo al documento que se va a imprimir.
Usualmente las facturas vienen un folio pre-impresio desde la imprenta (por lo menos en Mexico asi es), entonces capturas tu "pre-factura" con el numero que tu quieras, y cuando la mandas a imprimir le asignas manualmente el numero de factura de acuerdo al documento que este en la impresora listo para imprimirse.
Posted: Mon Jul 09, 2007 3:41 pm
by Patricio Avalos Aguirre
A mi me ha funcionado muy bien esta rutina que paso a explicar
dentro del sistema tengo un modulo de facturas directa, este automaticamente le asigna el numero siguiente
con una tabla de parametros que tiene un solo registro y estan todos los correlativos de los documentos
Code: Select all
REDEFINE GET aGet[id_numdocu-20,1];
VAR _numdocu ;
ID id_numdocu OF oDlg UPDATE ;
COLOR CLR_BLACK, RGB(255,255,200) ;
PICTURE "9999999999" ;
VALID vDocument( aGet, oLbx, aButton, oSay, lOt ) ;
WHEN cOpcion <> "I"
DEFINE TIMER oTmr INTERVAL 5000 ACTION ;
( Parame->( dbSkip(0) ), ;
_numdocu := Parame->Fact+1,;
aGet[id_numdocu-20,1]:Refresh() )
ACTIVATE TIMER oTmr
Eval( oTmr:bAction )
REDEFINE BUTTON aButton[_btnsave] ID 719 OF oDlg ;
ACTION ;
iif( SaveInfo( oLbx, aGet, lOt, oTmr, lArriendo ),;
Limpiar( oLbx, aGet, aButton, lOt ), NIL )
//FUNCION GRABAR
Static function SaveInfo( oLbx, aGet, lOt, oTmr, lArriendo )
//bla. validaciones...
if Parame->( !NetRlock() ) //bloqueo de tabla parametros
return( .f. )
endif
Eval( oTmr:bAction ) //sacamos el ultimo numero
oTmr:DeActivate() //desactivamos el timer
nDocu := _numdocu //traspaso el numero de factura a una variable temporal
if Docu_BF->( dbSeek( upper(left(_tipdocu,3)) + str( nDocu,10 ) ) )
//validamos el numero no exista en la base de dato
nOldFactu := nDocu
while Docu_BF->( dbSeek(upper(left(_tipdocu,3)) + Str(++nDocu, 10 ) ) )
enddo
if !MsgNoYes( "La "+_tipdocu +" nº "+ltrim(str(nOldFactu))+" ya existe, desea reemplazarla"+CRLF+;
"por esta nueva "+_tipdocu + " nº "+ltrim(str(nDocu)) )
dbUnlockAll()
aGet[id_numdocu-20,1]:Refresh()
oTmr:Activate()
return( .f. )
endif
endif
//grabamos...
parame->Fact := nDocu
//guardamos el numero de factura el la tabla parametros
dbCommitAll()
dbUnlockAll()
oTmr:Activate() //activamos nuevamante el timer
//imprime la factura...
return( .t. )
Espero que le sirva a alguien
Posted: Mon Jul 09, 2007 4:21 pm
by mic_vc
Estas dos funciones me han quitado ese problema en mis aplicaciones en red:
GetNewFolio() -> lo usas para mostrarle al usuario que folio se va a imprimir, si abres al mismo tiempo un dialogo en pantalla con los datos de la factura en 3 máquinas diferentes va aparecerá el mismo número
nFolio:=GetNewFolio(cRed+"\folios.dbf", "FOLIO")
REDEFINE SAY oSay PROMPT nFolio ID 101 OF oDlg
PutNewFolio() -> Lo usas cuando el usuario manda a imprimir, esta función va a escoger el folio que este disponible
nFolio:=PutNewFolio(cRed+"\folios.dbf", "FOLIO")
oSay:settext(nFolio)
De modo que si las llamadas no son en gran cantidad, en una sola base de datos puedes guardar varios folios
[FOLIOS.DBF]
BOLETA, N, 10, 0
NOTA, N, 10, 0
PRENDA, N, 10, 0
VEHICULO, N, 10, 0
FACTURA, N, 10, 0
/************************************************************************************/
/* Devuelve el próximo número de folio
/************************************************************************************/
function GetNewFolio(cDbf, cField)
Local nFolio:= 0, cAlias:=alias()
if file(cDbf)
dbusearea(.t.,, cDbf, "FOL", .t.)
If NetErr(); msgalert("Error al intentar abrir: "+CRLF+cDbf, "Abortando!"); return(nil); endif
FOL->( nFolio:= &(cField) + 1, dbclosearea() )
if( !empty(cAlias), dbselectarea(cAlias), )
else
msgstop("No se encontró la base de datos:"+CRLF+cDbf, "Abortando!")
endif
return(nFolio)
/************************************************************************************/
/* Aumenta el número de folio y lo devuelve
/************************************************************************************/
function PutNewFolio(cDbf, cField, nFolio)
Local lOk:=.t., cAlias:=alias()
if file(cDbf)
dbusearea(.t.,, cDbf, "FOL", .t.)
If NetErr(); msgalert("Error al intentar abrir: "+CRLF+cDbf, "Abortando!"); return(nil); endif
FOL->( if( lastrec() = 0, dbappend(), ) )
do
FOL->( if( flock(),;
( if( nFolio = NIL, nFolio := &(cField) + 1, ),;
dbfield(cField, nFolio), lOk:=.t. ),;
( lOk:=.f. ) ) )
until lOk
FOL->( dbcommit(), dbunlock(), dbclosearea() )
if( !empty(cAlias), dbselectarea(cAlias), )
else
msgstop("No se encontró la base de datos:"+CRLF+cDbf, "Abortando!")
endif
return(nFolio)
Saludos
Michel Carvajal
Posted: Mon Jul 09, 2007 5:07 pm
by sysctrl2
Fabian yo lo hago asi:
// HASLO HASTA QUE EL FOLIO NO EXISTA
do while .t.
nFactura := _miFolio('FACTURAS')
dbselectArea('facturas')
ordsetofucus(1)
if !dbseek( nFactura )
dbappend()
rlock()
field->folio := nFolio
dbcommit()
dbunlock()
exit //EXITO AL GRABAR .
endif
end
function _mifolio( cCampo )
local nValor := 0
local cFolio := ""
local cAli := _creaFolios() // ponemos en uso la tabla de consecutivos
dbselectArea(cAli)
nValor := val( &( cCampo) ) + 1
if rlock()
replace &(cCampo) with str( nValor,7 )
dbunlock()
endif
cFolio := &(cCampo)
(cAli)->( dbcloseArea() ) //cerramos la tabla de consecutivos
return ( _LLENA(cFolio,7) )
Esto no falla, saludos..
Posted: Tue Jul 10, 2007 5:19 pm
by antolin
Yo lo que hago es crear la factura en variables temporales con el ultimo numero calculado. Cuando le doy a guardar lo almaceno en la DBF correspondiente, pero si el numero de factura ya existia (porque otro usuario estaba creando otra con el mismo numero), calculo uno nuevo y advierto al usuario de tal echo. Si tuviera que imprimir la factura, primero la guardo (como acabo de explicar) y después la imprimo. Lo de las variables es para no editar los FIELDS del DBF directamente, por si lo que estoy creando no me sirve y no hay que guardarlo.
¿Imprfimir y arrepentirse? No es muy normal, pues una vez impresa la factura, si está en mano del Cliente, mejor no arrepentirse. En tal caso, si se da la situacion de que hay que romperla, pues se implementa una opción BORRAR FACTURA y ya está (-Hay gente reacia a incluir esa opcion, pero ya verá que a veces es el propio cliente quien lo solicita. Yo, en ese caso suelo no añadirla al MENU sino camuflarla como combinación de teclas en un GET concreto-).
Posted: Wed Jul 11, 2007 4:29 pm
by jacgsoft
Disculpen amigos, Pero hay veces en que por un tema simple, crean toda un Tormenta Ja Ja Ja. Como la mayoria dijo Los Numeros de Documentos se graban al final y no hay vuelta que darle.
Jaime
P.D.: Cuidemonos de un Derrame Cerebral