JSOTO Alta y compilacion G6 de programas CG, Cheques, Activos, Tesoreria, Repuestos e Informatica
Merge de main (ipprrp013/014/046/053) con conflictos resueltos: - mbsERP.4pw: ipprrp014 conserva ambos 4rp y su 4fd. - bin/ipprrp014.4rp: columnas MARGEN/CLASIF. + titulo IPPRRP014. Programas agregados a mbsERP.4pw (53 compilan y enlazan con fgl602): - CONTABILIDAD GENERAL, ACTIVOS FIJOS, REPUESTOS; grupos nuevos TESORERIA, CHEQUES e INFORMATICA (segprmt001 = seguridad2.0/segprmt0001.4gl). - irdir copiado de 3.20 PROYECTOS/irdir a PROYECTO/irdir; helpers de PROYECTOS/otrodir en FUNCIONES_IR (departamento -> irdepartamento.4gl). - Fuentes mas nuevos de 3.20: edprrp118, edprrp080, acprrp010, cgprmt022. - FUNCIONES: GeneraEntradaDiario.4gl a la version 3.20 + costoLiquidacion.4gl. - Ajustes G6: existe duplicado en irprgb000, fakeData de 22 campos y answer2 en irprmt036/020 (ApiMaintainC), selectOutputSimple en irprcs008, schemas de forms a smarmotech, referencia declarada en cgprmt005. - cgprmt005 sigue sin enlazar: requiere funciones de EXTERIOR. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -351,11 +351,14 @@ FUNCTION GeneraEntradaDiario(
|
||||
END IF
|
||||
#------------------------------------------------------------------------
|
||||
# INVENTARIO PRODUCTOS TERMINADOS
|
||||
# Ver GeneraEntradaInventario('P',...) mas abajo: la entrada de
|
||||
# inventario necesita las N lineas del documento (cod_mov/bodega),
|
||||
# que no caben en esta firma de valor unico.
|
||||
#------------------------------------------------------------------------
|
||||
IF tipoPrograma = 'INV PRODUCTOS' THEN
|
||||
END IF
|
||||
#------------------------------------------------------------------------
|
||||
# INVENTARIO REPUESTOS
|
||||
# INVENTARIO REPUESTOS -> ver GeneraEntradaInventario('R',...)
|
||||
#------------------------------------------------------------------------
|
||||
IF tipoPrograma = 'INV REPUESTOS' THEN
|
||||
END IF
|
||||
@@ -371,3 +374,624 @@ FUNCTION GeneraEntradaDiario(
|
||||
END IF
|
||||
|
||||
END FUNCTION
|
||||
|
||||
{
|
||||
FUNCION : GeneraEntradaInventario
|
||||
OBJETIVO : Armar las lineas debito/credito del asiento al mayor (cgtb00004)
|
||||
para UN documento de inventario (productos terminados o repuestos),
|
||||
valorizado con costoLiquidacion() y con las cuentas contables
|
||||
definidas por codigo de movimiento, replicando el criterio de
|
||||
EDPRRP080 (terminados) y EDPRRP118 (repuestos).
|
||||
PARAMETROS : usuario - usuario que crea el asiento (NOT NULL = consume secuencia)
|
||||
tipoInv - 'P' productos terminados / 'R' repuestos
|
||||
pnum_doc - num_doc del documento de inventario
|
||||
pcod_mov - codigo de movimiento
|
||||
pbodega - bodega del documento
|
||||
pfecha - fecha del documento
|
||||
RETORNA : generaE BOOLEAN (TRUE si armo al menos una linea),
|
||||
registroEntrada (mismo shape que GeneraEntradaDiario).
|
||||
NOTA : Solo toma las lineas con referenciaentrada IS NULL (idempotente:
|
||||
si se llama dos veces no duplica). El llamador inserta el arreglo
|
||||
en cgtb00004 (agregando numero_documento/cod_mov/bodega/
|
||||
sistema_auxiliar), y sella <tabla>.referenciaentrada = ED.xxx.
|
||||
DEBITO/CREDITO (por signo de cantidad_2, igual que los batch):
|
||||
entrada (cantidad >= 0): inventario DEBITO / contrapartida CREDITO
|
||||
salida (cantidad < 0): inventario CREDITO / contrapartida DEBITO
|
||||
CUENTAS : terminados -> iptb00005.cuenta_1/2/3 (material/labor/gasto por
|
||||
cod_mov) contra iptb00022.cuenta_no (por cod_cia).
|
||||
repuestos -> irtb00002.cuenta (por articulo, como EDPRRP118)
|
||||
contra iptb00022.cuenta_no (por cod_n).
|
||||
COSTEO : produccion (es_produccion=1) -> desglose material/labor/gasto de
|
||||
iptb00004. Compra/venta y repuestos -> costo unico costoLiquidacion()
|
||||
aplicado a la cuenta material (cuenta_1).
|
||||
}
|
||||
FUNCTION GeneraEntradaInventario(usuario, tipoInv, pnum_doc, pcod_mov, pbodega, pfecha)
|
||||
DEFINE
|
||||
usuario STRING,
|
||||
tipoInv CHAR(1),
|
||||
pnum_doc, pcod_mov, pbodega INT,
|
||||
pfecha DATE,
|
||||
entra VARCHAR(25),
|
||||
idrow INT,
|
||||
qsql STRING,
|
||||
es_prod SMALLINT,
|
||||
status_mov CHAR(1),
|
||||
cta_mat, cta_lab, cta_gas, cta_inv VARCHAR(14),
|
||||
cta_mat_imp, cta_mat_uso VARCHAR(14),
|
||||
dep_mat, dep_lab, dep_gas, dep_inv CHAR(1),
|
||||
usarCuentaItem SMALLINT,
|
||||
matStd, labStd, gasStd DEC(18, 4),
|
||||
unit, v_mat, v_lab, v_gas, v_total DEC(18, 4),
|
||||
detalle1 VARCHAR(100),
|
||||
depto_cia, dep_uso INT,
|
||||
dep_flag CHAR(1),
|
||||
nc, k, j, m, encontrado INT
|
||||
|
||||
#--- Candidatos de la linea y acumulador por (cuenta, departamento).
|
||||
#--- Convencion de 'valor': POSITIVO = DEBITO, NEGATIVO = CREDITO.
|
||||
DEFINE
|
||||
cand DYNAMIC ARRAY OF RECORD
|
||||
cuenta_no VARCHAR(14),
|
||||
valor DEC(18, 4)
|
||||
END RECORD,
|
||||
acum DYNAMIC ARRAY OF RECORD
|
||||
cuenta_no VARCHAR(14),
|
||||
departamento INT,
|
||||
valor DEC(18, 4),
|
||||
detalle VARCHAR(100)
|
||||
END RECORD
|
||||
|
||||
DEFINE lin RECORD
|
||||
cod_n, cod_grupo, cod_tipo, cod_sec INT,
|
||||
cantidad DEC(18, 4),
|
||||
departamento INT,
|
||||
cod_cia INT,
|
||||
descrip VARCHAR(180)
|
||||
END RECORD
|
||||
|
||||
DEFINE
|
||||
lineas DYNAMIC ARRAY OF RECORD
|
||||
cod_n, cod_grupo, cod_tipo, cod_sec INT,
|
||||
cantidad DEC(18, 4),
|
||||
departamento INT,
|
||||
cod_cia INT,
|
||||
descrip VARCHAR(180)
|
||||
END RECORD,
|
||||
i INT
|
||||
|
||||
DEFINE
|
||||
registroEntrada DYNAMIC ARRAY OF RECORD
|
||||
referenciaEntrada VARCHAR(25),
|
||||
fecha DATE,
|
||||
tipo CHAR(1),
|
||||
cuenta_no VARCHAR(8),
|
||||
departamento INT,
|
||||
detalle VARCHAR(100),
|
||||
debito, credito DEC(12, 2)
|
||||
END RECORD
|
||||
|
||||
CALL registroEntrada.clear()
|
||||
LET idrow = 0
|
||||
|
||||
#--- Secuencia de la entrada al diario (id 25 = entrada automatica inventario)
|
||||
CALL controlNumericoED(25, pfecha, usuario) RETURNING entra
|
||||
|
||||
#--- Cuentas contables
|
||||
IF tipoInv = 'P' THEN
|
||||
#--- Terminados: cuentas por codigo de movimiento (iptb00005), como EDPRRP080
|
||||
LET qsql =
|
||||
"SELECT ISNULL(status_mov,'E'), cuenta_1, cuenta_2, cuenta_3,
|
||||
cuenta_imp_material
|
||||
FROM marmotech.dbo.iptb00005 WHERE cod_mov = ?"
|
||||
PREPARE s_cta FROM qsql
|
||||
EXECUTE s_cta
|
||||
INTO status_mov, cta_mat, cta_lab, cta_gas, cta_mat_imp
|
||||
USING pcod_mov
|
||||
FREE s_cta
|
||||
LET usarCuentaItem = 0
|
||||
ELSE
|
||||
#--- Repuestos: la cuenta se toma del articulo (irtb00002.cuenta), como EDPRRP118.
|
||||
#--- Compras locales confirmadas; internacionales pendientes de validar con
|
||||
#--- finanzas (se asume el mismo criterio de EDPRRP118).
|
||||
LET cta_mat = NULL
|
||||
LET cta_lab = NULL
|
||||
LET cta_gas = NULL
|
||||
LET cta_mat_imp = NULL
|
||||
LET usarCuentaItem = 1
|
||||
END IF
|
||||
|
||||
#--- Preparados reutilizables dentro del ciclo
|
||||
LET qsql =
|
||||
"SELECT ISNULL(a.depto,'N') FROM marmotech.dbo.cgtb00001 a WHERE a.cuenta_no = ?"
|
||||
PREPARE s_dep FROM qsql
|
||||
|
||||
LET qsql =
|
||||
"SELECT a.cuenta_no, a.departamento FROM marmotech.dbo.iptb00022 a WHERE a.cod_cia = ?"
|
||||
PREPARE s_inv FROM qsql
|
||||
|
||||
IF tipoInv = 'P' THEN
|
||||
LET qsql =
|
||||
"SELECT TOP 1 ISNULL(a.es_produccion,0) FROM marmotech.dbo.iptb00002 a
|
||||
WHERE a.cod_n=? AND a.cod_grupo=? AND a.cod_tipo=? AND a.cod_sec=?"
|
||||
PREPARE s_esp FROM qsql
|
||||
LET qsql =
|
||||
"SELECT ISNULL(AVG(ISNULL(a.material,0)),0), ISNULL(AVG(ISNULL(a.labor,0)),0),
|
||||
ISNULL(AVG(ISNULL(a.gastos,0)),0)
|
||||
FROM marmotech.dbo.iptb00004 a
|
||||
WHERE a.cod_n=? AND a.cod_grupo=? AND a.cod_tipo=? AND a.cod_sec=?
|
||||
AND a.ano=YEAR(?) AND a.mes_fin=12 AND a.status_t IS NULL"
|
||||
PREPARE s_std FROM qsql
|
||||
ELSE
|
||||
LET qsql =
|
||||
"SELECT a.cuenta FROM marmotech.dbo.irtb00002 a
|
||||
WHERE a.cod_n=? AND a.cod_grupo=? AND a.cod_tipo=? AND a.cod_sec=?"
|
||||
PREPARE s_itemcta FROM qsql
|
||||
END IF
|
||||
|
||||
#--- Lectura de las lineas del documento (solo las no asentadas)
|
||||
IF tipoInv = 'P' THEN
|
||||
LET qsql =
|
||||
"SELECT c.cod_n,c.cod_grupo,c.cod_tipo,c.cod_sec,SUM(c.cantidad_2),
|
||||
ISNULL(c.departamento,0), MAX(e.cod_cia), MAX(e.descrip_esp)
|
||||
FROM marmotech.dbo.iptb00006 c
|
||||
INNER JOIN marmotech.dbo.iptb00002 e
|
||||
ON c.cod_n=e.cod_n AND c.cod_grupo=e.cod_grupo
|
||||
AND c.cod_tipo=e.cod_tipo AND c.cod_sec=e.cod_sec
|
||||
WHERE c.num_doc=? AND c.cod_mov=? AND c.bodega=?
|
||||
AND c.status_t IS NULL AND c.referenciaentrada IS NULL
|
||||
GROUP BY c.cod_n,c.cod_grupo,c.cod_tipo,c.cod_sec,c.departamento
|
||||
HAVING SUM(c.cantidad_2) <> 0"
|
||||
ELSE
|
||||
LET qsql =
|
||||
"SELECT b.cod_n,b.cod_grupo,b.cod_tipo,b.cod_sec,SUM(b.cantidad_2),
|
||||
ISNULL(b.sec_a,0), b.cod_n, MAX(a.descrip_esp)
|
||||
FROM marmotech.dbo.irtb00006 b
|
||||
INNER JOIN marmotech.dbo.irtb00002 a
|
||||
ON b.cod_n=a.cod_n AND b.cod_grupo=a.cod_grupo
|
||||
AND b.cod_tipo=a.cod_tipo AND b.cod_sec=a.cod_sec
|
||||
WHERE b.num_doc=? AND b.cod_mov=? AND b.bodega=?
|
||||
AND b.status_t IS NULL AND b.referenciaentrada IS NULL
|
||||
GROUP BY b.cod_n,b.cod_grupo,b.cod_tipo,b.cod_sec,b.sec_a,b.cod_n
|
||||
HAVING SUM(b.cantidad_2) <> 0"
|
||||
END IF
|
||||
PREPARE s_lin FROM qsql
|
||||
DECLARE c_lin CURSOR FOR s_lin
|
||||
|
||||
#--- Cargar las lineas a un arreglo ANTES de procesar, para no mantener el
|
||||
#--- cursor abierto mientras se hacen consultas anidadas (evita "connection busy")
|
||||
CALL lineas.clear()
|
||||
LET i = 0
|
||||
FOREACH c_lin USING pnum_doc, pcod_mov, pbodega INTO lin.*
|
||||
LET i = i + 1
|
||||
LET lineas[i].* = lin.*
|
||||
END FOREACH
|
||||
FREE c_lin
|
||||
|
||||
FOR i = 1 TO lineas.getLength()
|
||||
LET lin.* = lineas[i].*
|
||||
|
||||
#--- Valuacion segun tipo de producto
|
||||
LET matStd = 0
|
||||
LET labStd = 0
|
||||
LET gasStd = 0
|
||||
LET es_prod = 0
|
||||
LET unit = 0
|
||||
|
||||
IF tipoInv = 'P' THEN
|
||||
EXECUTE s_esp INTO es_prod
|
||||
USING lin.cod_n, lin.cod_grupo, lin.cod_tipo, lin.cod_sec
|
||||
IF es_prod IS NULL THEN LET es_prod = 0 END IF
|
||||
END IF
|
||||
|
||||
IF tipoInv = 'P' AND es_prod = 1 THEN
|
||||
#--- Produccion: desglose material/labor/gasto del estandard
|
||||
EXECUTE s_std INTO matStd, labStd, gasStd
|
||||
USING lin.cod_n, lin.cod_grupo, lin.cod_tipo, lin.cod_sec, pfecha
|
||||
LET v_mat = matStd * lin.cantidad
|
||||
LET v_lab = labStd * lin.cantidad
|
||||
LET v_gas = gasStd * lin.cantidad
|
||||
ELSE
|
||||
#--- Compra/venta y repuestos: costo unico a la cuenta material
|
||||
LET unit =
|
||||
costoLiquidacion(
|
||||
lin.cod_n, lin.cod_grupo, lin.cod_tipo, lin.cod_sec, pfecha, tipoInv)
|
||||
LET v_mat = unit * lin.cantidad
|
||||
LET v_lab = 0
|
||||
LET v_gas = 0
|
||||
END IF
|
||||
LET v_total = v_mat + v_lab + v_gas
|
||||
|
||||
IF v_total = 0 THEN
|
||||
CONTINUE FOR
|
||||
END IF
|
||||
|
||||
#--- Cuenta del articulo para repuestos sin cuenta por movimiento
|
||||
IF usarCuentaItem = 1 THEN
|
||||
LET cta_mat = NULL
|
||||
EXECUTE s_itemcta INTO cta_mat
|
||||
USING lin.cod_n, lin.cod_grupo, lin.cod_tipo, lin.cod_sec
|
||||
END IF
|
||||
|
||||
#--- Cuenta de inventario (contrapartida) y DEPARTAMENTO, por cod_cia.
|
||||
#--- El departamento contable del item sale de iptb00022 segun el cod_cia
|
||||
#--- que tenga en iptb00002; se aplica a TODA cuenta marcada depto='S'
|
||||
#--- en cgtb00001.
|
||||
LET cta_inv = NULL
|
||||
LET depto_cia = NULL
|
||||
EXECUTE s_inv INTO cta_inv, depto_cia USING lin.cod_cia
|
||||
|
||||
LET detalle1 =
|
||||
'INV ', tipoInv, ' DOC ', pnum_doc USING "<<<<<<<<",
|
||||
' MOV ', pcod_mov USING "<<<<", ' ', lin.descrip CLIPPED
|
||||
IF LENGTH(detalle1) > 100 THEN
|
||||
LET detalle1 = detalle1[1, 100]
|
||||
END IF
|
||||
|
||||
#--- Candidatos de esta linea. Convencion: valor POSITIVO = DEBITO,
|
||||
#--- NEGATIVO = CREDITO. Las contrapartidas aportan el valor invertido y
|
||||
#--- el inventario el total, por lo que la entrada CUADRA POR CONSTRUCCION.
|
||||
CALL cand.clear()
|
||||
LET nc = 0
|
||||
|
||||
#--- ORIGEN DEL ARTICULO (iptb00022 via iptb00002.cod_cia):
|
||||
#--- cod_cia 2 = PTOS. MAT.IMPORTADOS y 3 = PRODUCTOS IMPORTADOS llevan la
|
||||
#--- cuenta de material IMPORTADO (iptb00005.cuenta_imp_material) en lugar
|
||||
#--- de la cuenta_1 local. Mismo criterio que EDPRRP080. Labor y gasto NO
|
||||
#--- se cambian: siguen saliendo de cuenta_2 / cuenta_3.
|
||||
LET cta_mat_uso = cta_mat
|
||||
IF tipoInv = 'P' THEN
|
||||
IF lin.cod_cia = 2 OR lin.cod_cia = 3 THEN
|
||||
IF cta_mat_imp IS NOT NULL THEN
|
||||
LET cta_mat_uso = cta_mat_imp
|
||||
END IF
|
||||
END IF
|
||||
END IF
|
||||
|
||||
IF cta_mat_uso IS NOT NULL AND v_mat <> 0 THEN
|
||||
LET nc = nc + 1
|
||||
LET cand[nc].cuenta_no = cta_mat_uso CLIPPED
|
||||
LET cand[nc].valor = (0 - v_mat)
|
||||
END IF
|
||||
IF cta_lab IS NOT NULL AND v_lab <> 0 THEN
|
||||
LET nc = nc + 1
|
||||
LET cand[nc].cuenta_no = cta_lab CLIPPED
|
||||
LET cand[nc].valor = (0 - v_lab)
|
||||
END IF
|
||||
IF cta_gas IS NOT NULL AND v_gas <> 0 THEN
|
||||
LET nc = nc + 1
|
||||
LET cand[nc].cuenta_no = cta_gas CLIPPED
|
||||
LET cand[nc].valor = (0 - v_gas)
|
||||
END IF
|
||||
IF cta_inv IS NOT NULL AND v_total <> 0 THEN
|
||||
LET nc = nc + 1
|
||||
LET cand[nc].cuenta_no = cta_inv CLIPPED
|
||||
LET cand[nc].valor = v_total
|
||||
END IF
|
||||
|
||||
#--- Acumular por (cuenta, departamento): los items con el mismo cod_cia
|
||||
#--- se suman en una sola linea; si hay items con cod_cia distinto, la
|
||||
#--- misma cuenta se repite en la entrada con otro departamento y valor.
|
||||
FOR k = 1 TO nc
|
||||
|
||||
LET dep_flag = 'N'
|
||||
EXECUTE s_dep INTO dep_flag USING cand[k].cuenta_no
|
||||
IF dep_flag = 'S' THEN
|
||||
LET dep_uso = depto_cia
|
||||
ELSE
|
||||
LET dep_uso = NULL
|
||||
END IF
|
||||
|
||||
LET encontrado = 0
|
||||
FOR j = 1 TO acum.getLength()
|
||||
IF acum[j].cuenta_no = cand[k].cuenta_no THEN
|
||||
IF (acum[j].departamento IS NULL AND dep_uso IS NULL)
|
||||
OR (acum[j].departamento = dep_uso) THEN
|
||||
LET acum[j].valor = acum[j].valor + cand[k].valor
|
||||
LET encontrado = 1
|
||||
EXIT FOR
|
||||
END IF
|
||||
END IF
|
||||
END FOR
|
||||
|
||||
IF encontrado = 0 THEN
|
||||
LET m = acum.getLength() + 1
|
||||
LET acum[m].cuenta_no = cand[k].cuenta_no
|
||||
LET acum[m].departamento = dep_uso
|
||||
LET acum[m].valor = cand[k].valor
|
||||
LET acum[m].detalle = detalle1 CLIPPED
|
||||
END IF
|
||||
|
||||
END FOR
|
||||
|
||||
END FOR
|
||||
|
||||
#--- Emitir UNA linea por cada (cuenta, departamento) acumulado
|
||||
FOR j = 1 TO acum.getLength()
|
||||
IF acum[j].valor = 0 THEN
|
||||
CONTINUE FOR
|
||||
END IF
|
||||
LET idrow = idrow + 1
|
||||
LET registroEntrada[idrow].referenciaEntrada = entra
|
||||
LET registroEntrada[idrow].fecha = pfecha
|
||||
LET registroEntrada[idrow].tipo = '1'
|
||||
LET registroEntrada[idrow].cuenta_no = acum[j].cuenta_no
|
||||
LET registroEntrada[idrow].departamento = acum[j].departamento
|
||||
LET registroEntrada[idrow].detalle = acum[j].detalle
|
||||
IF acum[j].valor > 0 THEN
|
||||
LET registroEntrada[idrow].debito = acum[j].valor
|
||||
LET registroEntrada[idrow].credito = 0
|
||||
ELSE
|
||||
LET registroEntrada[idrow].debito = 0
|
||||
LET registroEntrada[idrow].credito = (0 - acum[j].valor)
|
||||
END IF
|
||||
END FOR
|
||||
|
||||
FREE s_lin
|
||||
FREE s_dep
|
||||
FREE s_inv
|
||||
IF tipoInv = 'P' THEN
|
||||
FREE s_esp
|
||||
FREE s_std
|
||||
ELSE
|
||||
FREE s_itemcta
|
||||
END IF
|
||||
|
||||
IF idrow = 0 THEN
|
||||
RETURN FALSE, registroEntrada
|
||||
END IF
|
||||
|
||||
RETURN TRUE, registroEntrada
|
||||
|
||||
END FUNCTION
|
||||
|
||||
{
|
||||
FUNCION : registraEntradaInventario
|
||||
OBJETIVO : Registrar en el mayor (cgtb00004) el asiento de UN documento de
|
||||
inventario y sellar la referencia ED en la tabla de movimientos.
|
||||
IMPORTANTE : Se ejecuta DENTRO de la transaccion del programa llamador.
|
||||
NO hace BEGIN WORK ni COMMIT WORK. Si retorna FALSE el llamador
|
||||
debe hacer ROLLBACK WORK.
|
||||
PARAMETROS : usuario, tipoInv ('P'/'R'), num_doc, cod_mov, bodega, fecha
|
||||
RETORNA : ok BOOLEAN, entra VARCHAR(25) con la referencia ED generada
|
||||
(ok = TRUE y entra = NULL significa que no habia nada pendiente
|
||||
por asentar, lo cual no es un error).
|
||||
}
|
||||
FUNCTION registraEntradaInventario(usuario, tipoInv, pnum_doc, pcod_mov, pbodega, pfecha)
|
||||
DEFINE
|
||||
usuario STRING,
|
||||
tipoInv CHAR(1),
|
||||
pnum_doc, pcod_mov, pbodega INT,
|
||||
pfecha DATE,
|
||||
genera BOOLEAN,
|
||||
entra VARCHAR(25),
|
||||
sistema VARCHAR(2),
|
||||
tipodoc VARCHAR(10),
|
||||
tabla STRING,
|
||||
qsql STRING,
|
||||
idx INT,
|
||||
t_debito, t_credito DEC(18, 2)
|
||||
|
||||
DEFINE
|
||||
registroEntrada DYNAMIC ARRAY OF RECORD
|
||||
referenciaEntrada VARCHAR(25),
|
||||
fecha DATE,
|
||||
tipo CHAR(1),
|
||||
cuenta_no VARCHAR(8),
|
||||
departamento INT,
|
||||
detalle VARCHAR(100),
|
||||
debito, credito DEC(12, 2)
|
||||
END RECORD
|
||||
|
||||
LET genera = FALSE
|
||||
LET entra = NULL
|
||||
|
||||
CALL GeneraEntradaInventario(
|
||||
usuario, tipoInv, pnum_doc, pcod_mov, pbodega, pfecha)
|
||||
RETURNING genera, registroEntrada
|
||||
|
||||
#--- Sin lineas pendientes por asentar: no es error
|
||||
IF NOT genera THEN
|
||||
RETURN TRUE, entra
|
||||
END IF
|
||||
|
||||
LET entra = registroEntrada[1].referenciaEntrada
|
||||
LET tipodoc = 'INV'
|
||||
|
||||
#--- Guardian de cuadre (equivalente a verificaCuadre() de los batch).
|
||||
#--- Si falta una cuenta configurada (iptb00022 / iptb00005 / irtb00002) la
|
||||
#--- contrapartida no se genera y el asiento quedaria descuadrado: se aborta
|
||||
#--- para no ensuciar el mayor.
|
||||
LET t_debito = 0
|
||||
LET t_credito = 0
|
||||
FOR idx = 1 TO registroEntrada.getLength()
|
||||
IF registroEntrada[idx].cuenta_no IS NULL THEN
|
||||
CONTINUE FOR
|
||||
END IF
|
||||
LET t_debito = t_debito + registroEntrada[idx].debito
|
||||
LET t_credito = t_credito + registroEntrada[idx].credito
|
||||
END FOR
|
||||
|
||||
IF t_debito <> t_credito THEN
|
||||
DISPLAY "ED FALLO: ASIENTO DESCUADRADO ref=", entra CLIPPED,
|
||||
" debito=", t_debito, " credito=", t_credito,
|
||||
" dif=", (t_debito - t_credito)
|
||||
DISPLAY "ED FALLO: detalle de las lineas armadas ->"
|
||||
FOR idx = 1 TO registroEntrada.getLength()
|
||||
DISPLAY " cta=", registroEntrada[idx].cuenta_no,
|
||||
" depto=", registroEntrada[idx].departamento,
|
||||
" debito=", registroEntrada[idx].debito,
|
||||
" credito=", registroEntrada[idx].credito
|
||||
END FOR
|
||||
DISPLAY "ED FALLO: revise que el cod_mov tenga cuenta_1/2/3 en ",
|
||||
"iptb00005/irtb00005 y que el cod_cia del item tenga cuenta_no en iptb00022"
|
||||
RETURN FALSE, entra
|
||||
END IF
|
||||
|
||||
IF tipoInv = 'P' THEN
|
||||
LET sistema = 'IP'
|
||||
LET tabla = 'marmotech.dbo.iptb00006'
|
||||
ELSE
|
||||
LET sistema = 'IR'
|
||||
LET tabla = 'marmotech.dbo.irtb00006'
|
||||
END IF
|
||||
|
||||
#--- Lineas del asiento al mayor
|
||||
LET qsql =
|
||||
"INSERT INTO marmotech.dbo.cgtb00004
|
||||
(fecha,tipo,ref,cuenta_no,departamento,detalle_1,debito,credito,
|
||||
us_crea,fech_crea,numero_documento,cod_mov,bodega,
|
||||
sistema_auxiliar,tipo_documento)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,GETDATE(),?,?,?,?,?)"
|
||||
PREPARE s_insed FROM qsql
|
||||
|
||||
FOR idx = 1 TO registroEntrada.getLength()
|
||||
IF registroEntrada[idx].cuenta_no IS NULL THEN
|
||||
CONTINUE FOR
|
||||
END IF
|
||||
EXECUTE s_insed
|
||||
USING registroEntrada[idx].fecha,
|
||||
registroEntrada[idx].tipo,
|
||||
registroEntrada[idx].referenciaEntrada,
|
||||
registroEntrada[idx].cuenta_no,
|
||||
registroEntrada[idx].departamento,
|
||||
registroEntrada[idx].detalle,
|
||||
registroEntrada[idx].debito,
|
||||
registroEntrada[idx].credito,
|
||||
usuario,
|
||||
pnum_doc,
|
||||
pcod_mov,
|
||||
pbodega,
|
||||
sistema,
|
||||
tipodoc
|
||||
IF STATUS < 0 THEN
|
||||
DISPLAY "ED FALLO: INSERT cgtb00004 status=", STATUS,
|
||||
" ", SQLERRMESSAGE
|
||||
DISPLAY " ref=", entra CLIPPED,
|
||||
" cta=", registroEntrada[idx].cuenta_no,
|
||||
" depto=", registroEntrada[idx].departamento,
|
||||
" debito=", registroEntrada[idx].debito,
|
||||
" credito=", registroEntrada[idx].credito
|
||||
DISPLAY " doc=", pnum_doc, " mov=", pcod_mov, " bodega=", pbodega,
|
||||
" sistema=", sistema
|
||||
FREE s_insed
|
||||
RETURN FALSE, entra
|
||||
END IF
|
||||
END FOR
|
||||
FREE s_insed
|
||||
|
||||
#--- Sellar la referencia en las lineas del documento
|
||||
LET qsql =
|
||||
"UPDATE ",
|
||||
tabla,
|
||||
" SET referenciaentrada = ?
|
||||
WHERE num_doc = ? AND cod_mov = ? AND bodega = ?
|
||||
AND status_t IS NULL AND referenciaentrada IS NULL"
|
||||
PREPARE s_updref FROM qsql
|
||||
EXECUTE s_updref USING entra, pnum_doc, pcod_mov, pbodega
|
||||
IF STATUS < 0 THEN
|
||||
DISPLAY "ED FALLO: UPDATE ", tabla, ".referenciaentrada status=", STATUS,
|
||||
" ", SQLERRMESSAGE
|
||||
DISPLAY " ref=", entra CLIPPED, " doc=", pnum_doc,
|
||||
" mov=", pcod_mov, " bodega=", pbodega
|
||||
FREE s_updref
|
||||
RETURN FALSE, entra
|
||||
END IF
|
||||
FREE s_updref
|
||||
|
||||
RETURN TRUE, entra
|
||||
|
||||
END FUNCTION
|
||||
|
||||
{
|
||||
FUNCION : anulaEntradaPorRef
|
||||
OBJETIVO : Anular en el mayor (cgtb00004) las lineas de UNA entrada ED,
|
||||
marcandolas status_t = 'E'. Mismo criterio que usa
|
||||
ccprmt016 para anular los asientos de CxC.
|
||||
IMPORTANTE : Se ejecuta DENTRO de la transaccion del programa llamador.
|
||||
NO hace BEGIN WORK ni COMMIT WORK.
|
||||
RETORNA : TRUE si anulo o si no habia nada que anular; FALSE si fallo.
|
||||
NOTA : NO se borra la referencia de la tabla de movimientos: el
|
||||
movimiento queda con status_t='E' y conserva su referencia
|
||||
como rastro de cual asiento se anulo.
|
||||
}
|
||||
FUNCTION anulaEntradaPorRef(usuario, refED)
|
||||
DEFINE
|
||||
usuario STRING,
|
||||
refED VARCHAR(25),
|
||||
qsql STRING
|
||||
|
||||
IF refED IS NULL THEN
|
||||
RETURN TRUE
|
||||
END IF
|
||||
IF LENGTH(refED) = 0 THEN
|
||||
RETURN TRUE
|
||||
END IF
|
||||
|
||||
LET qsql =
|
||||
"UPDATE marmotech.dbo.cgtb00004
|
||||
SET status_t = 'E', us_mod = ?, fech_mod = GETDATE()
|
||||
WHERE ref = ? AND status_t IS NULL"
|
||||
PREPARE s_anuED FROM qsql
|
||||
EXECUTE s_anuED USING usuario, refED
|
||||
|
||||
IF STATUS < 0 THEN
|
||||
DISPLAY "ED FALLO: no se pudo anular el asiento ", refED CLIPPED,
|
||||
" status=", STATUS, " ", SQLERRMESSAGE
|
||||
FREE s_anuED
|
||||
RETURN FALSE
|
||||
END IF
|
||||
|
||||
FREE s_anuED
|
||||
RETURN TRUE
|
||||
|
||||
END FUNCTION
|
||||
|
||||
{
|
||||
FUNCION : anulaEntradaInventario
|
||||
OBJETIVO : Anular el asiento al mayor de UN documento de inventario.
|
||||
Busca la referencia ED sellada en la tabla de movimientos y
|
||||
delega en anulaEntradaPorRef.
|
||||
PARAMETROS : usuario, tipoInv ('P'/'R'), num_doc, cod_mov,
|
||||
bodega (puede venir NULL: entonces no filtra por bodega,
|
||||
que es como anula irprmt066).
|
||||
IMPORTANTE : Dentro de la transaccion del llamador. Si retorna FALSE el
|
||||
llamador debe hacer ROLLBACK WORK.
|
||||
RETORNA : ok BOOLEAN, refED de la entrada anulada (NULL si no habia)
|
||||
}
|
||||
FUNCTION anulaEntradaInventario(usuario, tipoInv, pnum_doc, pcod_mov, pbodega)
|
||||
DEFINE
|
||||
usuario STRING,
|
||||
tipoInv CHAR(1),
|
||||
pnum_doc, pcod_mov, pbodega INT,
|
||||
refED VARCHAR(25),
|
||||
tabla STRING,
|
||||
qsql STRING,
|
||||
ok BOOLEAN
|
||||
|
||||
IF tipoInv = 'P' THEN
|
||||
LET tabla = 'marmotech.dbo.iptb00006'
|
||||
ELSE
|
||||
LET tabla = 'marmotech.dbo.irtb00006'
|
||||
END IF
|
||||
|
||||
#--- La referencia se busca SIN filtrar status_t: al momento de llamarnos
|
||||
#--- las lineas del movimiento ya pueden estar marcadas 'E'.
|
||||
LET refED = NULL
|
||||
LET qsql =
|
||||
"SELECT MAX(a.referenciaentrada) FROM ",
|
||||
tabla,
|
||||
" a WHERE a.num_doc = ? AND a.cod_mov = ? AND (a.bodega = ? OR ? IS NULL)"
|
||||
PREPARE s_refanu FROM qsql
|
||||
EXECUTE s_refanu INTO refED USING pnum_doc, pcod_mov, pbodega, pbodega
|
||||
FREE s_refanu
|
||||
|
||||
IF refED IS NULL THEN
|
||||
#--- Documento sin asiento (anterior al automatico, o costo cero)
|
||||
RETURN TRUE, refED
|
||||
END IF
|
||||
|
||||
LET ok = anulaEntradaPorRef(usuario, refED)
|
||||
|
||||
RETURN ok, refED
|
||||
|
||||
END FUNCTION
|
||||
Reference in New Issue
Block a user