Page 1 of 3

ALGORITMO PARA CREAR PLAN DE CUENTA CONTABLE

Posted: Sat Jul 20, 2019 6:39 pm
by joseluisysturiz
Saludos, estoy por iniciar un pequeno modulo contable y las gestione de balance, analitico, etc, las puedo conseguir en un libro de contalidada...pero mi gran duda es creando el plan de cuenta, es decir, como validar el nivel de las cuentas, si es de movimiento o de mayor, etc..se que los codigos 1 al 6 deberian ser las cuentas de MAYOR, es decir totalizadoras, asi lo creo..el detalles es cuando empiezo a crear las cuentas de movimiento y hasta que nivel deberia de llegar, no se casi nada, para no decir nada, de contabilidad, se cosas muy basicas, pero leyendo aprendo rapido, mi detalles como dije es para crear el modulo de las cuentas contablas..y si es posible por el tipo de data hacerlo con un TREE en ves de un browse o que es lo mas recomendable..espero sus opiniones y sugerencias,,,y si hay algun sample..mejor todabia...gracias..saludos...

Re: ALGORITMO PARA CREAR PLAN DE CUENTA CONTABLE

Posted: Sat Jul 20, 2019 7:13 pm
by hmpaquito
En Plan cuentas yo prefiero q convivan niveles superiores e inferior.
Asi del grupo Gastos existirá:
6
60
600
6000
60000001

Si el usuario teclea 60000002 entonces busca nivel anterior, 4 dig, y si no existe sugerir como alta ese nivel y asi sucesivamente con resto niveles.

Re: ALGORITMO PARA CREAR PLAN DE CUENTA CONTABLE

Posted: Sat Jul 20, 2019 7:53 pm
by joseluisysturiz
hmpaquito wrote:En Plan cuentas yo prefiero q convivan niveles superiores e inferior.
Asi del grupo Gastos existirá:
6
60
600
6000
60000001

Si el usuario teclea 60000002 entonces busca nivel anterior, 4 dig, y si no existe sugerir como alta ese nivel y asi sucesivamente con resto niveles.
hmpaquito, gracias por responder, como es la estructura de un plan de cuenta lo se...lo que necesito es saber como hacer la validacion cuando el usuario entre las cuentas, para saber si es de movimiento o tatalzadora, aqui en Venezuela se usa mucho esta estructura, ejemplo:

1 ACTIVO
1.1 XXXX
1.1.1 HHHHHH
1.1.1.1 cta de movimiento
1.1.2 AAAAAAA
1.1.2.1 cta de movimiento

2 PASIVO
2.1
2.1.1 cta de movimiento
...etc

lo que requiero es saber cuando se agrega la cuenta a que nivel o tip va hacer, si maestra(totalizadora), detalle(movimientos), gracias, saludos... :shock:

Re: ALGORITMO PARA CREAR PLAN DE CUENTA CONTABLE

Posted: Sat Jul 20, 2019 10:22 pm
by leandro
Jose Luis Buenas tardes

En mysql actualizo los saldos con la siguiente consulta:

Code: Select all

UPDATE tbl_ctas_2019 SET bb_debi01=bb_debi01-0.00,bb_cred01=bb_cred01-250000.00,usuari='001',ufecha='20190720',uhoras='17:20:16' WHERE bb_cuenta='110505' or bb_cuenta='1105' or bb_cuenta='11' or bb_cuenta='1'
 

Re: ALGORITMO PARA CREAR PLAN DE CUENTA CONTABLE

Posted: Sun Jul 21, 2019 2:25 am
by joseluisysturiz
leandro wrote:Jose Luis Buenas tardes

En mysql actualizo los saldos con la siguiente consulta:

Code: Select all

UPDATE tbl_ctas_2019 SET bb_debi01=bb_debi01-0.00,bb_cred01=bb_cred01-250000.00,usuari='001',ufecha='20190720',uhoras='17:20:16' WHERE bb_cuenta='110505' or bb_cuenta='1105' or bb_cuenta='11' or bb_cuenta='1'
 
Leandro gracias por tu interes en responder, pero creo aun no me han entendido...lo que necesito es el algoritmo para cargar las cuentas contable o crear el plan y controlar sus niveles, saber que la cuenta seleccionada es o no una cuenta de movimientos, y cuando el usuario vaya seleccionar la cuenta contable para asignarle el monto del movimiento, deshabilitar las cuentas maestro o solo permitirle seleccionar dicha cuenta de movimiento, las demas cosas de como cargar comprobante, hacer calculo e impresiones las domino, mi explicacion la hago en base a como mas o menos se maneja la contabilidad aca en Venezuela, asumo que es casi igual en todas partes, gracias... :shock:

Re: ALGORITMO PARA CREAR PLAN DE CUENTA CONTABLE

Posted: Sun Jul 21, 2019 4:15 pm
by Armando
José Luis:

Si entendí bien, al menos lo que yo hago es, como te explicó hmpaquito, al armar el plan de cuentas
primero debes dar de alta la cuenta de primer nivel
6

luego la de segundo nivel, validando que ya existe la del nivel inmediato superior, en este caso la 6
6-1

luego la de tercer nivel, validando que ya existe la del nivel inmediato superior, en este caso la 6-1
6-1-1

Y así sucesivamente

Al registrar los movimientos o pólizas, debes validar que la cuenta que recibe el movimiento sea
la de último nivel, recuerda que las de niveles superiores son acumulativas,en el ejemplo de arriba,
sería la 6-1-1. cómo?, yo capturo los movimientos en una tabla temporal, al finalizar la captura
de la póliza, valido que el importe del DEBE y HABER sean los mismos, es la regla de la partida doble.

Si todo va bien, paso los movimientos de la tabla temporal a la tabla que conservará todas las
pólizas del ejercicio fiscal.

Espero te ayude en algo.

Saludos

Re: ALGORITMO PARA CREAR PLAN DE CUENTA CONTABLE

Posted: Sun Jul 21, 2019 4:34 pm
by joseluisysturiz
Armando wrote:José Luis:

Si entendí bien, al menos lo que yo hago es, como te explicó hmpaquito, al armar el plan de cuentas
primero debes dar de alta la cuenta de primer nivel
6

luego la de segundo nivel, validando que ya existe la del nivel inmediato superior, en este caso la 6
6-1

luego la de tercer nivel, validando que ya existe la del nivel inmediato superior, en este caso la 6-1
6-1-1

Y así sucesivamente

Al registrar los movimientos o pólizas, debes validar que la cuenta que recibe el movimiento sea
la de último nivel, recuerda que las de niveles superiores son acumulativas,en el ejemplo de arriba,
sería la 6-1-1. cómo?, yo capturo los movimientos en una tabla temporal, al finalizar la captura
de la póliza, valido que el importe del DEBE y HABER sean los mismos, es la regla de la partida doble.

Si todo va bien, paso los movimientos de la tabla temporal a la tabla que conservará todas las
pólizas del ejercicio fiscal.

Espero te ayude en algo.

Saludos
Armando, por alli va el tiro, lo que debo determinar hasta q nivel van hacer acumulativas de forma basica y luego a partir del nivel X validar q la seleccionada es de movimiento, porque digo eso.? pues porque si existe una cuenta maestra nivel 1(ej. 6) que son las cuentas de mayor hasta donde tengo entendido, si creo una cuenta 6.1 y no hay mas inferiores, por decir 6.1.1, esta 6.1 no deberia permitir movimientos ya que ese seria un nivel 2 y son otros tipos de cuenta, por lo menos es lo que he visto en la contabilidad venezolana, no se si me equivoco en lo que digo ni como la manejarias tu o la de otros paises...gracias..saludos... :shock:

Re: ALGORITMO PARA CREAR PLAN DE CUENTA CONTABLE

Posted: Mon Jul 22, 2019 12:14 am
by Armando
José Luis:

La regla es que todas las cuentas de último nivel son las únicas que reciben movimientos,
las de nivel superior solo son acumulativas.

Tomando en cuenta esta regla solo necesitas validar que los movimientos afecten cuentas
de último nivel.

En el ejemplo anterior solo la cuenta 6-1-1 podrá recibir movimientos, las superiores 6-1 y
6 solo serán acumulativas.

Saludos

Re: ALGORITMO PARA CREAR PLAN DE CUENTA CONTABLE

Posted: Mon Jul 22, 2019 12:29 am
by joseluisysturiz
Armando wrote:José Luis:

La regla es que todas las cuentas de último nivel son las únicas que reciben movimientos,
las de nivel superior solo son acumulativas.

Tomando en cuenta esta regla solo necesitas validar que los movimientos afecten cuentas
de último nivel.

En el ejemplo anterior solo la cuenta 6-1-1 podrá recibir movimientos, las superiores 6-1 y
6 solo serán acumulativas.

Saludos
Armando entiendo claramente tu punto y estoy de acuerdo, pero hasta lo que he visto en la contabilidad de venezuela hay ciertos niveles que no deberian aceptar movimientos aunque sea la ultima, o no se si estare equivocado, te pregunto y seguimos con tu ejemplo, si tengo una cuenta 6 y una cuenta 6.1, para ti la cuenta 6.1 es la que recibe los movimientos y la 6 obviamente es la acumulativa.?

si tu respúesta es SI, entonces aqui hasta donde se, vuelvo y repito a menos que me equivoque, la cuenta 6.1 no podria recibir movimientos ya que en el nivel de plan de cuenta es una cuenta acumulativa, hay que crearle ajuro una cuenta 6.1.1...es lo que entiendo y donde deberia de validar a partir de que nivel de cuenta empiezan a recibir movimientos-

voy a leer un poco un libro de contabilidad muy famoso aca y vere si aclaro ese punto, si estoty equivocado entonces sera un poco facil el control asi como tu lo dices...espero tu comentario o de algun colega venezolano que haya realizado algun modulo contable y que pueda aclarar la duda que expreso...gracias...saludos... :shock:

Re: ALGORITMO PARA CREAR PLAN DE CUENTA CONTABLE

Posted: Mon Jul 22, 2019 1:01 am
by Armando
José Luis:

Desafortunadamente no conozco la contabilidad de tu país pero me parece que la contabilidad es
universal, respecto a tu última pregunta donde piensas que debes abrir una cuenta 6-1-1 que será
la que reciba los movimientos, NO, no necesariamente debe ser así, habrá cuentas que tengan solo
dos niveles, otras necesitan tener tres niveles y seguramente habrá otras que deben abrir un
cuarto nivel, eso depende el nivel de detalle que el área de finanzas quiere controlar.

Por ejemplo, la cuenta de bancos seria mas o menos así:

1 Bancos
1-1 Banco del ahorro nacional
1-1-1 Moneda nacional
1-1-2 Moneda extranjera
1-2 Banco de la ilusión
1-2-1 Moneda nacional
1-2-2 Moneda extranjera

Como ves, aquí solo es necesario un tercer nivel, pero en otra área, por ejemplo almacén

40 Almacenes
40-1 Almacén central
40-1-1 Producto terminado
40-1-1 Relojes
40-1-1-2 Para dama
40-1-2-3 Para caballero

40-2 Almacén del norte
40-2-1 Producto terminado
40-2-1 Relojes
40-2-1-2 Para dama
40-2-2-3 Para caballero

Como ves en estas cuentas se necesitan 4 niveles y es válido.

Saludos

Re: ALGORITMO PARA CREAR PLAN DE CUENTA CONTABLE

Posted: Mon Jul 22, 2019 1:29 am
by joseluisysturiz
Armando, con lo que expones me das la razon, que las cuentas de movimientos siempre estaran a partir de una nivel 3, y es lo que estoy aclarando en la validacion, aunque la contabilidad es algo universal, no para todos es igual, fijate que en tu ejemplo del almacen las cuentas

40 Almacenes -> ACUMULATIVA NIVEL 1
40-1 Almacén central -> ACUMULATIVA NIVEL 2
40-1-1 Producto terminado -> DE MOVIMIENTO NIVEL 3

40-1-1 Relojes -> ACUMULATIVA NIVEL 3
40-1-1-2 Para dama -> DE MOVIMIENTO NIVEL 4
40-1-2-3 Para caballero -> DE MOVIMIENTO NIVEL 4

lo que queria era aclarar mi duda de que nunca una cuenta de movimiento va ser de NIVEL 2, por eso el ejemplo de 6 y 6.1, gracias por tu aclaratoria e intercambio de conocimientos contables, aca dejo unas paginas que aclaran aun mas, cualquier duda estare escribiendo o si deseas compartir mi correo es joseluisysturiz@yahoo.com saludos... :shock:

http://www.venezuelacuenta.com.ve/el-pl ... -contable/

https://es.wikipedia.org/wiki/Plan_de_cuentas

Re: ALGORITMO PARA CREAR PLAN DE CUENTA CONTABLE

Posted: Mon Jul 22, 2019 2:40 pm
by ACC69
joseluisysturiz wrote:Armando, con lo que expones me das la razon, que las cuentas de movimientos siempre estaran a partir de una nivel 3, y es lo que estoy aclarando en la validacion, aunque la contabilidad es algo universal, no para todos es igual, fijate que en tu ejemplo del almacen las cuentas

40 Almacenes -> ACUMULATIVA NIVEL 1
40-1 Almacén central -> ACUMULATIVA NIVEL 2
40-1-1 Producto terminado -> DE MOVIMIENTO NIVEL 3

40-1-1 Relojes -> ACUMULATIVA NIVEL 3
40-1-1-2 Para dama -> DE MOVIMIENTO NIVEL 4
40-1-2-3 Para caballero -> DE MOVIMIENTO NIVEL 4

lo que queria era aclarar mi duda de que nunca una cuenta de movimiento va ser de NIVEL 2, por eso el ejemplo de 6 y 6.1, gracias por tu aclaratoria e intercambio de conocimientos contables, aca dejo unas paginas que aclaran aun mas, cualquier duda estare escribiendo o si deseas compartir mi correo es joseluisysturiz@yahoo.com saludos... :shock:

http://www.venezuelacuenta.com.ve/el-pl ... -contable/

https://es.wikipedia.org/wiki/Plan_de_cuentas

Hola buenos dias Ing. Jose Luis le paso el codigo de un modulo de alta de cuentas contables de 1 a 4 niveles de cuentas, espero que te ayude .

Code: Select all

#include "FiveWin.ch"
*#Include "BtnGet.Ch"

STATIC S06, S08, S15
STATIC oDlg
STATIC cCuenta,cDescribe,nTCuenta,cCtaProv,nTProveedor,nTOperacion,lAp_SN,lIVA,lSNMov,cDesOpera
STATIC cNombFM,cCurp,cDireccion,cCiudad,cRfc,cCp,nTelefono,nFax
STATIC nNivel
STATIC oGet,oSay, oBtn,lNuevo,lOk, oRad1, oRad2


Memvar S04, oMOpc, cNombUsua, cNombre

//------------------------------------------------------------------------------
FUNCTION CATALOGO()
 AltCat(.F.,"cCta")
RETURN NIL

//------------------------------------------------------------------------------
FUNCTION AltCat(lPol,AltaCta)
 LOCAL oItem:=oMOpc

 PUBLIC nNUMEMP, nMES, nANO

 oGet   := Array(15)
 oSay   := Array(1)
 oBtn   := Array(2)

 nNivel := 0

 IF lPol
     cCuenta := AltaCta
 ELSE
     cCuenta := Space(19)
 ENDIF

 lAp_SN      := (S04)->AP_SEGNG
 cDescribe   := SPACE(65)
 nTCuenta    := 2
 nTProveedor := 2
 cCtaProv    := SPACE(12)
 nTOperacion := 0
 cDesOpera   := ""
 lIVA        := .F.
 lSNMov      := .F.
 cNombFM     := SPACE(65)
 cCurp       := SPACE(18)
 cDireccion  := SPACE(80)
 cCiudad     := SPACE(36)
 cRfc        := SPACE(14)
 cCp         := SPACE(14)
 nTelefono   := 0
 nFax        := 0
 lNuevo      := .F.

 S06 := Abre_Dbf(6,6)   // ABRE TIPOPERA.DBF
 S08 := Abre_Dbf(8,8)   // ABRE CATCTAxA.DBF
 S15 := Abre_Dbf(15,15) // ABRE CATPROVD.DBF

 DEFINE DIALOG oDlg RESOURCE "CATALOGO" TITLE "Altas catálogo de cuentas"
  REDEFINE GET   oGet[01] VAR cCuenta      ID 101     OF oDlg ;
                                                          PICTURE "@K ###################";
                                                          ACTION (ListCat(@cCuenta,S08,"cCuenta",oGet[01]));
                                                          UPDATE VALID VALCTA()
  REDEFINE GET   oGet[02] VAR cDescribe    ID 102     OF oDlg PICTURE "@K"                UPDATE VALID V_DESCRIP(cDescribe)
  REDEFINE RADIO oGet[03] VAR nTCuenta     ID 103,104 OF oDlg                             UPDATE
  REDEFINE RADIO oGet[04] VAR nTProveedor  ID 105,106 OF oDlg                             UPDATE
 *oRad1:aItems[1]:SetText("QUE ONDA")
  REDEFINE CHECKBOX oGet[05] VAR lIVA      ID 107 OF oDlg                                  //UPDATE
  REDEFINE CHECKBOX oGet[06] VAR lSNMov    ID 108 OF oDlg                                 WHEN lAp_SN

  REDEFINE GET   oGet[07] VAR nTOperacion  ID 109     OF oDlg PICTURE "9" WHEN IF(nTCuenta = 2 .OR. nTProveedor = 1, .F., .T.);
                                                                           ACTION (A_TOPERA(@nTOperacion,S06)) VALID VTOPERA()
  REDEFINE SAY   oSay[01] PROMPT cDesOpera ID 150 OF oDlg PICTURE "@!" UPDATE

  REDEFINE GET   oGet[08] VAR cNombFM      ID 110 OF oDlg PICTURE "@!" UPDATE;
                                                           WHEN IF(nTCuenta = 2 .OR. nTProveedor = 1, .F., .T.)
  REDEFINE GET   oGet[09] VAR cCurp        ID 111 OF oDlg PICTURE "@!" UPDATE;
                                                           WHEN IF(nTCuenta = 2 .OR. nTProveedor = 1, .F., .T.) VALID invStr(cCurp)
  REDEFINE GET   oGet[10] VAR cDireccion   ID 112 OF oDlg PICTURE "@!" UPDATE;
                                                           WHEN IF(nTCuenta = 2 .OR. nTProveedor = 1, .F., .T.)
  REDEFINE GET   oGet[11] VAR cCiudad      ID 113 OF oDlg PICTURE "@!" UPDATE;
                                                           WHEN IF(nTCuenta = 2 .OR. nTProveedor = 1, .F., .T.)
  REDEFINE GET   oGet[12] VAR cRfc         ID 114 OF oDlg PICTURE "@!" UPDATE;
                                                           WHEN IF(nTCuenta = 2 .OR. nTProveedor = 1, .F., .T.);
                                                           VALID V_RFC(cRFC)
  REDEFINE GET   oGet[13] VAR cCp          ID 115 OF oDlg PICTURE "@K #######" UPDATE;
                                                           WHEN IF(nTCuenta = 2 .OR. nTProveedor = 1, .F., .T.)
  REDEFINE GET   oGet[14] VAR nTelefono    ID 116 OF oDlg PICTURE "@9" UPDATE;
                                                           WHEN IF(nTCuenta = 2 .OR. nTProveedor = 1, .F., .T.)
  REDEFINE GET   oGet[15] VAR nFax         ID 117 OF oDlg PICTURE "@9" UPDATE;
                                                           WHEN IF(nTCuenta = 2 .OR. nTProveedor = 1, .F., .T.)

 oGet[01]:bKeyDown := { |nKey| IIF( nKey == VK_F2,(oGet[01]:Assign(),Eval( oGet[01]:bAction )),"" ) }
 oGet[01]:cToolTip := "Presiona F2"
 oGet[05]:bKeyDown := { |nKey| IIF( nKey == VK_F2,(oGet[05]:Assign(),Eval( oGet[05]:bAction )),"" ) }
 oGet[05]:cToolTip := "Presiona F2"

   REDEFINE BUTTON oBtn[1] ID 201 OF oDlg ACTION REG_DATO(lPol)
   REDEFINE BUTTON oBtn[2] ID 202 OF oDlg ACTION oDlg:END()
 ACTIVATE DIALOG oDlg CENTERED VALID (oItem:Enable(),.T.)

 Close_Dbf(6,S06)

 IF !lPol
     Close_Dbf(8,S08)
 ELSE
     Close_Dbf(8,S08)
 ENDIF

 Close_Dbf(15,S15)
RETURN NIL

//------------------------------------------------------------------------------
STATIC FUNCTION VALCTA()
 LOCAL I, cCta:=SPACE(16),xDig1,xDig2,xDig3,xDig4,xCtaDig,nPos1,nPos2,lProv :=.F.

 cCuenta := FORMATO1("cCuenta", cCuenta,.T.) // Despliega formato con guion en el get
 cCta    := FORMATO1("cCuenta", cCuenta,.F.) // Despliega formato sin guion a buscar

 // INICIA PROCESOS EN CAMPOS DE DIGITOS
 * VALIDA SI SOBREPASA MAS DE X DIGITOS POR NIVEL DE CUENTAS SI MARCA ERROR DE "*"

 FOR I = 1 TO LEN(cCuenta)
      IF SUBS(cCuenta, I, 1) == "*" .OR. I > LEN(cCuenta)
          MsgInfo("Cuenta inválida "+TRIM(cCuenta),"Confirme")

          cCuenta := SPACE(19)

          oGet[01]:Refresh()

          RETURN .F.
      ENDIF
 END FOR

 * XXXX-XXXX-XXXX-XXXX

 xDig1 := Val(SubStr(cCuenta,1,4))
 xDig2 := Val(SubStr(cCuenta,6,4))
 xDig3 := Val(SubStr(cCuenta,11,4))
 xDig4 := Val(SubStr(cCuenta,16,4))

 DO CASE
    CASE xDig1 > 0 .AND. xDig2 = 0 .AND. xDig3 = 0 // NIVEL 1
          nNivel := 1

    CASE xDig1 > 0 .AND. xDig2 > 0 .AND. xDig3 = 0 // NIVEL 2
          nNivel  := 2
          xCtaDig := STRZERO(xDig1,4) + "0000" + "0000" + "0000"

          (S08)->(DBSeek(xCtaDig))

          IF !EMPTY(xDig2)
              IF (S08)->TIPONAT = 'D'
                  MsgInfo('La cuenta tiene subcuentas, no puede ser de detalle',"Confirme")

                  RETURN .F.
              ENDIF
          ENDIF

          IF (S08)->(!FOUND())
              MsgInfo('La cuenta '+Ext_xNiv(xCtaDig)+' nivel '+STR(nNivel)+' no tiene antecedentes ', "Confirme")

              oGet[01]:Refresh()

              RETURN .F.
          ENDIF

    CASE xDig1 > 0 .AND. xDig2 > 0 .AND. xDig3 > 0 .AND. xDig4 = 0 // NIVEL 3
          nNivel  := 3
          xCtaDig := STRZERO(xDig1,4) + STRZERO(xDig2,4) + "0000" + "0000"

          (S08)->(DBSeek(xCtaDig))

          IF !EMPTY(xDig2)
              IF (S08)->TIPONAT = 'D'
                  MsgInfo('La cuenta tiene subcuentas, no puede ser de detalle',"Confirme")

                  RETURN .F.
              ENDIF
          ENDIF

          IF (S08)->(!FOUND())
              MsgInfo('La cuenta '+Ext_xNiv(xCtaDig)+' nivel '+STR(nNivel)+' no tiene antecedentes ', "Confirme")

              oGet[01]:Refresh()

              RETURN .F.
          ENDIF

    CASE xDig1 > 0 .AND. xDig2 > 0 .AND. xDig3 > 0 .AND. xDig4 > 0  // NIVEL 4
          nNivel  := 4
          xCtaDig := STRZERO(xDig1,4) + STRZERO(xDig2,4) + STRZERO(xDig3,4) + "0000"

          (S08)->(DBSeek(xCtaDig))

          IF !EMPTY(xDig3)
              IF (S08)->TIPONAT = 'D'
                  MsgInfo('La cuenta tiene subcuentas, no puede ser de detalle',"Confirme")

                  RETURN .F.
              ENDIF
          ENDIF

          IF (S08)->(!FOUND())
              MsgInfo('La cuenta '+Ext_xNiv(xCtaDig)+' nivel '+STR(nNivel)+' no tiene antecedentes ', "Confirme")

              oGet[01]:Refresh()

              RETURN .F.
          ENDIF
    OTHERWISE
          RETURN .F.
 ENDCASE

 (S08)->(DBSeek(cCta))

 IF (S08)->(Found())
     cDescribe   := (S08)->DESCRIP
     nTCuenta    := IF(AllTrim((S08)->TIPONAT) == "D" ,1,2)
     nTProveedor := IF(AllTrim((S08)->TIPOPRV) == "C" ,1,2)
     nTOperacion := (S08)->TIPOPERA
     lIVA        := (S08)->AP_IVA
     lSNMov      := (S08)->MOVSN

     *MsgInfo(nTProveedor)

     DO CASE
        CASE (S08)->NIVSUM = 1 .AND. (S08)->TIPONAT == "D" //.AND. (S08)->TIPOPRV == "P"
              nPos1 := 0
              nPos2 := 1
              lProv := .T.
        CASE (S08)->NIVSUM = 2 .AND. (S08)->TIPONAT == "D" //.AND. (S08)->TIPOPRV == "P"
              nPos1 := 3
              nPos2 := 5
              lProv := .T.
        CASE (S08)->NIVSUM = 3 .AND. (S08)->TIPONAT == "D" //.AND. (S08)->TIPOPRV == "P"
              nPos1 := 7
              nPos2 := 9
              lProv := .T.
        CASE (S08)->NIVSUM = 4 .AND. (S08)->TIPONAT == "D" //.AND. (S08)->TIPOPRV == "P"
              nPos1 := 11
              nPos2 := 13
              lProv := .T.
     ENDCASE

     IF lProv
         (S15)->(DBSeek(IF(lProv, SUBS(cCta,nPos1,2),"")+IF(lProv, SUBS(cCta,nPos2,4),"")))

         cNombFM    := IF(nTProveedor=1,(S08)->DESCRIP ,(S15)->NOMPROV)
         cCurp      := IF(nTProveedor=1,(S08)->C_U_R_P ,(S15)->C_U_R_P)
         cDireccion := IF(nTProveedor=1,(S08)->DIRECCIO,(S15)->DIRECCIO)
         cCiudad    := IF(nTProveedor=1,(S08)->CIUDAD  ,(S15)->CIUDAD)
         cRfc       := IF(nTProveedor=1,(S08)->R_F_C   ,(S15)->R_F_C)
         cCp        := IF(nTProveedor=1,(S08)->CODPOST ,(S15)->CODPOST)
         nTelefono  := IF(nTProveedor=1,(S08)->TELEFONO,(S15)->TELEFONO)
         nFax       := IF(nTProveedor=1,(S08)->TELEFFAX,(S15)->TELEFFAX)
     ENDIF

     (S06)->(DBSeek(STR(nTOperacion,1)))

     cDesOpera   := (S06)->DESCRIP
     lNuevo      := .F.
 ELSE
     lNuevo      := .T.
 ENDIF

 AEval( oGet,{|o| o:Refresh()} )
 AEval( oSay,{|o| o:Refresh()} )

 Release I, cCta, xDig1, xDig2, xDig3, xCtaDig
RETURN (.T.)

//------------------------------------------------------------------------------
STATIC FUNCTION V_DESCRIP(cDescribe)
 cNombFM := cDescribe

 oGet[07]:REFRESH()
RETURN (.T.)


//------------------------------------------------------------------------------
STATIC FUNCTION VTOPERA()
 LOCAL lRet := .T., cCta:=SPACE(16),nPos1,nPos2,lProv

 cCta    := FORMATO1("cCuenta", cCuenta,.F.) // Despliega formato sin guion a buscar

 DO CASE
    CASE nNivel = 1 .AND. nTCuenta = 1 .AND. nTProveedor = 2
          nPos1 := 0
          nPos2 := 1
          lProv := .T.
     CASE nNivel = 2 .AND. nTCuenta = 1 .AND. nTProveedor = 2
          nPos1 := 3
          nPos2 := 5
          lProv := .T.
     CASE nNivel = 3 .AND. nTCuenta = 1 .AND. nTProveedor = 2
          nPos1 := 7
          nPos2 := 9
          lProv := .T.
     CASE nNivel = 4 .AND. nTCuenta = 1 .AND. nTProveedor = 2
          nPos1 := 11
          nPos2 := 13
          lProv := .T.
 ENDCASE

 IF lProv .AND. nTCuenta = 1 .AND. nTProveedor = 2
     (S15)->(DBSeek(IF(lProv, SUBS(cCta,nPos1,2),"")+IF(lProv, SUBS(cCta,nPos2,4),"")))

    ** cNombFM     := (S15)->NOMPROV    //  porque aquí lo borra...tengo que checar ese detalle...!
     cCurp      := (S15)->C_U_R_P
     cDireccion := (S15)->DIRECCIO
     cCiudad    := (S15)->CIUDAD
     cRfc       := (S15)->R_F_C
     cCp        := (S15)->CODPOST
     nTelefono  := (S15)->TELEFONO
     nFax       := (S15)->TELEFFAX

     AEval( oGet,{|o| o:Refresh()} )
 ENDIF

 DbSelectArea(S06)

 (S06)->(DbSeek(STR(nTOperacion,1)))

 IF FOUND()
     nTOperacion := (S06)->CVETIPO
     cDesOpera   := (S06)->DESCRIP
 ELSE
     MsgAlert("No existe tipo de operación","Confirme")

     lRet := .F.
 ENDIF

 oGet[05]:Refresh()
 oGet[06]:Refresh()
RETURN (lRet)

//------------------------------------------------------------------------------
STATIC FUNCTION V_RFC(RFCf)
 LOCAL I := 0, lRet:=.T.

 IF RFCf = " "
     MsgInfo("El primer digito del RFC deber ser una letra")
     lRet := .F.
 ELSE
     FOR I = 1 TO LEN(RFCf)
           IF SUBS(RFCf,I,1) == "-" .OR. SUBS(RFCf,I-1,1) == " "
               MsgInfo("Favor de no teclear guion o dejar espacios en blanco")

               lRet := .T.
           ENDIF
     NEXT
 ENDIF

 oGet[11]:Refresh()
 Release I
RETURN (.T.)

//------------------------------------------------------------------------------
STATIC FUNCTION invStr( __cTexto )
 LOCAL aText1, cNew, n, cTemp, g, x

 aText1 = ARRAY (LEN ( __cTexto ) )
 cNew = ""

 FOR n = 1 TO LEN( __cTexto )
      cTemp = LEFT( __cTexto, n )
      aText1[ n ] = RIGHT( cTemp, 1 )

      MsgInfo(aText1[ n ])
 NEXT n

 x = 1

 FOR g = LEN( __cTexto ) TO 1 STEP -1
     cNew =  aText1[ x ] + cNew
     x = x + 1

     MsgInfo(cNew)
 NEXT g

 MsgInfo(cNew)
RETURN (.t.)

//------------------------------------------------------------------------------
STATIC FUNCTION REG_DATO(lPol)
 LOCAL cCta, nRecno1,nRecno2, lProv:=.F., nPos1,nPos2

 nRecno1:= (S08)->(RecNo())
 nRecno2:= (S15)->(RecNo())
 cCta   := FORMATO1("cCuenta", cCuenta,.F.) // Despliega formato sin guion a buscar

 (S08)->(DBSeek(cCta))

 * XXXX-XXXX-XXXX-XXXX
 * 1    5    9    13

 DO CASE
    CASE nNivel = 1 .AND. nTCuenta = 1 .AND. nTProveedor = 2
          nPos1 := 0
          nPos2 := 1
          lProv := .T.
    CASE nNivel = 2 .AND. nTCuenta = 1 .AND. nTProveedor = 2
          nPos1 := 3
          nPos2 := 5
          lProv := .T.
    CASE nNivel = 3 .AND. nTCuenta = 1 .AND. nTProveedor = 2
          nPos1 := 7
          nPos2 := 9
          lProv := .T.
    CASE nNivel = 4 .AND. nTCuenta = 1 .AND. nTProveedor = 2
          nPos1 := 11
          nPos2 := 13
          lProv := .T.
 ENDCASE

 IF lNuevo // Si agrega nuevo registro
     (S08)->(DBAppend())

     (S08)->FECALTA := DATE()
     (S08)->REGHORA := AMPM(TIME())
     (S08)->NICKUSUA:= cNombUsua
     (S08)->NOMBUSUA:= cNombre
 ELSE
     (S08)->(DBGoTo(nRecno1))
 ENDIF

 IF !OCUPADO(S08)  // Bloquea registro
     (S08)->CUENTAS   := cCta
     (S08)->NIVSUM    := nNivel
     (S08)->DESCRIP   := cDescribe
     (S08)->TIPONAT   := IF(nTCuenta    == 1, "D", "A")
     (S08)->GRUPOCTA  := 0
     (S08)->TIPOPRV   := IF(nTProveedor == 1, "C", "P")
     (S08)->TIPOPERA  := nTOperacion
     (S08)->AP_SN     := (S04)->AP_SEGNG               // Temporal, mientras se termine de programar... \\
     (S08)->AP_IVA    := lIVA
     (S08)->MOVSN     := lSNMov //IF((S04)->AP_SEGNG, .T., .F.) // Temporal, mientras se termine de programar... \\
     (S08)->NOMBRE    := cNombFM
     (S08)->C_U_R_P   := cCurp
     (S08)->DIRECCIO  := cDireccion
     (S08)->CIUDAD    := cCiudad
     (S08)->R_F_C     := cRfc
     (S08)->CODPOST   := cCp
     (S08)->TELEFONO  := nTelefono
     (S08)->TELEFFAX  := nFax

     (S08)->(DbCommit())
     (S08)->(DbUnlock())
 ENDIF

 (S15)->(DBSeek(IF(lProv, SUBS(cCta,nPos1,2),"")+IF(lProv, SUBS(cCta,nPos2,4),"")))

 IF lNuevo .AND. nTCuenta = 1 .AND. nTProveedor = 2 // Si agrega nuevo registro
     (S15)->(DBAppend())
 ELSE
     (S15)->(DBGoTo(nRecno2))
 ENDIF

 IF !OCUPADO(S15) .AND. nTCuenta = 1 .AND. nTProveedor = 2 .AND. lProv // Bloquea
     (S15)->SUBCTA   := IF(lProv, SUBS(cCta,nPos1,2),"")
     (S15)->CTAPROV  := IF(lProv, SUBS(cCta,nPos2,4),"")
     (S15)->NOMPROV  := cNombFM
     (S15)->C_U_R_P  := cCurp
     (S15)->DIRECCIO := cDireccion
     (S15)->CIUDAD   := cCiudad
     (S15)->R_F_C    := cRfc
     (S15)->CODPOST  := cCp
     (S15)->TELEFONO := nTelefono
     (S15)->TELEFFAX := nFax

     (S15)->(DbCommit())
     (S15)->(DbUnlock())
 ENDIF

 cCuenta     := Space(19)
 cDescribe   := SPACE(65)
 nTCuenta    := 2
 nTProveedor := 2
 cCtaProv    := SPACE(12)
 nTOperacion := 0
 lIVA        := .F.
 lSNMov      := .F.
 cDesOpera   := ""
 cNombFM     := SPACE(65)
 cCurp       := SPACE(18)
 cDireccion  := SPACE(80)
 cCiudad     := SPACE(36)
 cRfc        := SPACE(14)
 cCp         := SPACE(14)
 nTelefono   := 0
 nFax        := 0

 AEval( oGet,{|o| o:Refresh()} )

 IF lPol
     oDlg:End()
 ELSE
    oGet[1]:SetFocus()
    oBtn[1]:oJump := oGet[01]
  * oDlg:SetFocus()
 ENDIF

 Release cCta, nRecno1, nRecno2
RETURN NIL

//------------------------------------------------------------------------------
STATIC FUNCTION ListCat(Ctaf,S08,VarCta,oGetCpo)
 LOCAL lRet:= .T.

 Default oGetCpo := NIL

 IF SelCta(Ctaf,S08)
     DO CASE
        CASE VarCta = "cCuenta"
             cCuenta := Ext_xNiv((S08)->CUENTAS)
     ENDCASE
 ENDIF

 oGetCpo:Refresh()

 Release oDLbx1, oLbx1, cCta2
RETURN NIL

//------------------------------------------------------------------------------
STATIC FUNCTION A_TOPERA(nTOpera,S06)
 LOCAL oDLbx1, oLbx1, lSel := .F.

 DbSelectArea(S06)

 (S06)->(DbGoTop())

 DEFINE DIALOG oDLbx1 RESOURCE "VCATALAG" TITLE "Catálogo tipo de operación"
  REDEFINE LISTBOX oLbx1 FIELDS STR((S06)->CVETIPO), SUBS((S06)->DESCRIP,1,36) ;
                         HEADER "Tipo", "Descripción" ;
                         SIZES 85,200 ;
                         ALIAS (S06)->(ALIAS()) ID 101 OF oDLbx1

  oLbx1:lCellStyle := .T.
  oLbx1:bLogicLen  := {||(S06)->(OrdKeyCount())}
*  oLbx1:lAdjLastCol:= .F.
  oLbx1:nClrForeHead:= CLR_RED
  oLbx1:bLDblClick  := {||oDLbx1:END()}
  oLbx1:bKeyDown    := {| nKey| IF(nKey = VK_RETURN, (lSel:=.T.,oDLbx1:End()),)}

 ACTIVATE DIALOG oDLbx1

 IF lSel
     nTOperacion := (S06)->CVETIPO
     cDesOpera   := (S06)->DESCRIP
 ENDIF

 oGet[05]:Refresh()
 oGet[06]:Refresh()

 Release oDLbx1, oLbx1
RETURN (lSel)

Saludos ing. Jose Luis y buen dia a todos.

Atte: Adriano C. C.

Re: ALGORITMO PARA CREAR PLAN DE CUENTA CONTABLE

Posted: Mon Jul 22, 2019 2:59 pm
by joseluisysturiz
Buen dia ACC, gracias por tu ayuda, reviso lo enviado y luego comento o pregunto por alguna duda, que seguro la habra, jeje..gracias...saudos... :shock:

Re: ALGORITMO PARA CREAR PLAN DE CUENTA CONTABLE

Posted: Mon Jul 22, 2019 3:37 pm
by EASYSOFT
Buenos días.

Yo utilizo de la siguiente manera.

1.- Una tabla para aa estructura del plan de cuentas la estructura de la tabla es.
codigo, nombre, digitos ejemplo.

codigo = 1
nombre = titulo
digitos = 1


codigo = 2
nombre = grupo
digitos = 2


codigo = 3
nombre = subgrupo
digitos = 4


codigo = 4
nombre = cuentas nivel 1
digitos = 6

codigo = 5
nombre = cuentas nivel 2
digitos = 8
etc.


2.- Plan de cuentas su estructura es.

cuenta,nombre,nivel(aquí va la estructura),movimientos,mayor , ejemplo

cuenta = 1
nombre = Activo
nivel = 1
movimientos = N
mayor = (va en blanco)

cuenta = 11
nombre = Activo Corriente
nivel = 2
movimientos = N
mayor = 1

cuenta = 1101
nombre = Efectivo o equivalente
nivel = 3
movimientos = N
mayor = 11

cuenta = 110101
nombre = Bancos
nivel = 4
movimientos = N
mayor = 1101

cuenta = 11010101
nombre = Nombre del banco
nivel = 5
movimientos = S
mayor = 110101

Desde la cuenta de nivel 4 ya puedes hacerle de movimientos con esta manera puedes estructurar el plan de cuentas de acuerdo a cada empresa ya que se manejan cada una de forma diferente, con la estructura controlas todo el tema, espero haberme explicado, puedes contactarme a _@hotmail.com


Saludos,

_

Re: ALGORITMO PARA CREAR PLAN DE CUENTA CONTABLE

Posted: Mon Jul 22, 2019 3:54 pm
by leandro
Jose Luis Buenos días

Aqui en Colombia los diferentes niveles de las cuentas tienen nombre, así:

1 (1 Dígito - Clase)
11 (2 Dígitos - Grupo)
1105 (4 Dígitos - Cuentas)
110501 (6 Dígitos - SubCuentas)
11050101 (8 Dígitos - Auxiliares)

Y simplemente cuando cuando hago la validación en la digitación, hago el filtro por las subcuentas o las auxiliares.

Esta consulta que me permite determinar si la subcuenta tiene cuentas auxiliares asignadas:

Code: Select all

cons = "SELECT count(*) AS nro_aux FROM plan WHERE subs(cuenta,1,6)='110505' AND tipo_cuenta='A'";