Usar un autoincremental para el numero de factura no es para nada recomendable.
creo que lo adedcuado es usar transacciones, y un campo que mantega el ultimo numero de factura, al estar en una transaccion todo el proceso esta protegido incluido el nuevo numero de factura.
uso tdolphin, y unos metodos propios de grabacion, y una funcion para obtener el nuevo numero de factura.
tengo una tabla control con un campos que son los contadores de documentos. en el caso de la venta es CONT_FACT.
FUNCTION Fact_Grabar()
LOCAL lGrabado := FALSE
IF lCredito .and. nNumClie == 0
MsgAlert( "El cliente no esta autorizado a facturar al credito.", "Alerta" )
RETURN FALSE
ENDIF
TRY
oServer:BeginTransaction()
IF ( nNumFact := IncContador( "CONT_FACT" ) ) > 0
IF !Fact_Imprimir()
Throw( ErrorNew( "Error de impresión.", 0, 0, "Error en la Impresión de factura de venta." ) )
ENDIF
oServer:Insert2( "MFACTURAS", { { "NUM_FACT" , nNumFact },;
{ "FECHA" , dFecha },;
{ "TC" , nTC },;
{ "CREDITO" , lCredito },;
{ "PLAZO" , nPlazo },;
{ "NUM_VEND" , nNumVend },;
{ "NOM_VEND" , cNomVend },;
{ "REFERENCIA", cReferencia },;
{ "NUM_CLIE" , nNumClie },;
{ "NOM_CLIE" , cNomClie },;
{ "DIR_CLIE" , cDirClie },;
{ "RUC_CLIE" , cRucClie },;
{ "TEL_CLIE" , cTelClie },;
{ "EXONERADO" , lExonerado },;
{ "TIPOPAGO" , cTipoPago },;
{ "REFEPAGO" , cRefePago },;
{ "NOTA" , cNota },;
{ "PORCDESC" , nPorcDesc },;
{ "SUBTOTAL" , nSubTotal },;
{ "DESCUENTO" , nDescuento },;
{ "IVA" , nImpuesto },;
{ "TOTAL" , nTotal },;
{ "SALDO" , IIf( lCredito, nTotal, 0 ) },;
{ "PAGADA" , !lCredito },;
{ "ANULADA" , FALSE } } )
DETA->( DBGoTop() )
DO WHILE !DETA->( Eof() )
oServer:Insert2( "DFACTURAS", { { "NUM_FACT", nNumFact },;
{ "NUM_PROD", DETA->NUM_PROD },;
{ "NOM_PROD", DETA->NOM_PROD },;
{ "UMEDIDA" , DETA->UMEDIDA },;
{ "SERVICIO", DETA->SERVICIO },;
{ "CANTIDAD", DETA->CANTIDAD },;
{ "PRECIO" , DETA->PRECIO },;
{ "VALOR" , DETA->VALOR },;
{ "P_DESC" , DETA->P_DESC },;
{ "V_DESC" , DETA->V_DESC },;
{ "G_IVA" , DETA->G_IVA },;
{ "V_IVA" , DETA->V_IVA },;
{ "SERIAL" , DETA->SERIAL } } )
IF !DETA->SERVICIO
oServer:Execute2( "UPDATE PRODUCTOS SET EXISTENCIA=EXISTENCIA-%1 WHERE NUM_PROD=%2 LIMIT 1", { DETA->CANTIDAD, DETA->NUM_PROD } )
ENDIF
DETA->( DBSkip() )
ENDDO
IF nNumProf>0
oServer:Execute2( "DELETE FROM DPROFORMAS WHERE NUM_PROF=%1", { nNumProf } )
oServer:Execute2( "DELETE FROM MPROFORMAS WHERE NUM_PROF=%1", { nNumProf } )
ENDIF
ENDIF
oServer:CommitTransaction()
oQryFact:ReQuery()
lGrabado := TRUE
CATCH oError
oServer:RollBack()
ShowError( oError )
END
IF lGrabado
oBrw:GoBottom()
oBrw:Refresh()
ELSE
oBrw:Refresh()
ENDIF
DETA->( DBGoTop() )
RETURN lGrabado