Ayuda Numeracion de Facturas en Red

Ayuda Numeracion de Facturas en Red

Postby Databaselab2002 » Sun Jul 08, 2007 2:07 am

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
Databaselab2002
 
Posts: 142
Joined: Sun Oct 09, 2005 1:36 am

Postby Francisco Horta » Sun Jul 08, 2007 3:15 am

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
Francisco Horta
 
Posts: 845
Joined: Sun Oct 09, 2005 5:36 pm
Location: la laguna, mexico.

Re: Ayuda Numeracion de Facturas en Red

Postby FiveWiDi » Sun Jul 08, 2007 11:07 am

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 los campos de la dBF, el resto de puestos de la red no ven los cambios.
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
FiveWiDi
 
Posts: 1077
Joined: Mon Oct 10, 2005 2:38 pm

Postby jllinas » Sun Jul 08, 2007 3:14 pm

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...
Julio Llinás
Visita mi Blog en http://mangucybernetico.blogspot.com/
xHarbour 1.1.0 + FWH810 + Borland 5.5.1
User avatar
jllinas
 
Posts: 189
Joined: Fri Oct 14, 2005 12:33 am
Location: Santo Domingo, Dominican Republic

Postby R.F. » Sun Jul 08, 2007 3:46 pm

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
Saludos
R.F.
R.F.
 
Posts: 840
Joined: Thu Oct 13, 2005 7:05 pm

Re: Ayuda Numeracion de Facturas en Red

Postby lubin » Mon Jul 09, 2007 5:06 am

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
User avatar
lubin
 
Posts: 439
Joined: Fri Dec 09, 2005 12:41 am
Location: Lima, Peru

Postby pymsoft » Mon Jul 09, 2007 8:27 am

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.
Pedro Gonzalez
User avatar
pymsoft
 
Posts: 383
Joined: Tue Oct 11, 2005 1:01 pm
Location: Savona - Italia

Postby jose_murugosa » Mon Jul 09, 2007 10:39 am

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)
Saludos/Regards,
José Murugosa
FWH + Harbour + Bcc7. Una seda!
User avatar
jose_murugosa
 
Posts: 1145
Joined: Mon Feb 06, 2006 4:28 pm
Location: Uruguay

Postby R.F. » Mon Jul 09, 2007 2:37 pm

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.
Saludos
R.F.
R.F.
 
Posts: 840
Joined: Thu Oct 13, 2005 7:05 pm

Postby Patricio Avalos Aguirre » Mon Jul 09, 2007 3:41 pm

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  Expand view
   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
Saludos
Patricio

__________________________________________________________________
Version: Harbour 3.2.0dev (r1307082134),Compiler: Borland C++ 5.8.2 (32-bit)
PCode version: 0.3, FWH 13.2
http://www.sialm.cl
User avatar
Patricio Avalos Aguirre
 
Posts: 1059
Joined: Fri Oct 07, 2005 1:56 pm
Location: La Serena, Chile

Postby mic_vc » Mon Jul 09, 2007 4:21 pm

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
El poder del hombre es ilimitado cuando ha vencido la pereza, cuando confía en el feliz resultado de lo que quiere con todas sus fuerzas, cuando sabe que es capaz de conseguirlo, cuando reconoce que al tropezar siempre adelanta dos pasos.
mic_vc
 
Posts: 1
Joined: Fri May 19, 2006 9:29 pm

Postby sysctrl2 » Mon Jul 09, 2007 5:07 pm

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..
Cesar Cortes Cruz
SysCtrl Software
Mexico

' Sin +- FWH es mejor "
User avatar
sysctrl2
 
Posts: 957
Joined: Mon Feb 05, 2007 7:15 pm

Postby antolin » Tue Jul 10, 2007 5:19 pm

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-).
antolin
 
Posts: 492
Joined: Thu May 10, 2007 8:30 pm
Location: Sevilla

Postby jacgsoft » Wed Jul 11, 2007 4:29 pm

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
User avatar
jacgsoft
 
Posts: 104
Joined: Fri Nov 24, 2006 9:03 pm
Location: Lima - Peru


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 38 guests