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
|
||||
@@ -0,0 +1,149 @@
|
||||
{
|
||||
FUNCION : costoLiquidacion
|
||||
OBJETIVO : Determinar el costo unitario que debe tener un producto terminado
|
||||
o un repuesto para valorizar el asiento de inventario en linea,
|
||||
de acuerdo a la liquidacion de mercancia (cttb00013) o al costo
|
||||
estandard. Centraliza el criterio de costeo que antes aplicaba
|
||||
el usuario de forma manual.
|
||||
DESARROLLADO : Equipo Tecnologia (Juan Soto)
|
||||
FECHA : 14 Septiembre 2026
|
||||
|
||||
REGLA DE COSTO (definida por el usuario):
|
||||
- Repuestos (ptipoInv = 'R'):
|
||||
Siempre costo estandard irtb00013.costo_st (ano del documento, mes_fin = 12).
|
||||
|
||||
- Terminados (ptipoInv = 'P'):
|
||||
* iptb00002.es_produccion = TRUE -> SIEMPRE costo estandard iptb00004
|
||||
(material + labor + gastos, mes_fin = 12).
|
||||
* es_produccion = FALSE (compra/venta):
|
||||
- Se busca la ULTIMA liquidacion DEL MES del documento en cttb00013.
|
||||
(Solo el mes: si la liquidacion fue en un mes anterior, lqprrp004
|
||||
ya actualizo el costo estandard, por lo que ese ya lo refleja.)
|
||||
- Si hay liquidacion del mes Y su cantidad liquidada > existencia actual
|
||||
(SUM iptb00006.cantidad_2 WHERE status_t IS NULL) -> costo_lq.
|
||||
- En caso contrario (existencia >= liquidada, o no hay liquidacion
|
||||
del mes) -> costo estandard iptb00004.
|
||||
|
||||
NOTA: usa nombres calificados marmotech.dbo.* igual que GeneraEntradaDiario.4gl y
|
||||
controlNumericoED.4gl, para leer siempre la BD correcta sin depender de la
|
||||
conexion del programa llamador.
|
||||
}
|
||||
|
||||
FUNCTION costoLiquidacion(pcod_n, pcod_grupo, pcod_tipo, pcod_sec, pfecha, ptipoInv)
|
||||
DEFINE
|
||||
pcod_n, pcod_grupo, pcod_tipo, pcod_sec INT,
|
||||
pfecha DATE,
|
||||
ptipoInv CHAR(1),
|
||||
costo DEC(18, 4),
|
||||
costo_std DEC(18, 4),
|
||||
xcosto_lq DEC(18, 4),
|
||||
cant_lq DEC(18, 4),
|
||||
existencia DEC(18, 4),
|
||||
es_prod SMALLINT,
|
||||
qsql STRING
|
||||
|
||||
LET costo = 0
|
||||
LET costo_std = 0
|
||||
LET xcosto_lq = 0
|
||||
LET cant_lq = 0
|
||||
LET existencia = 0
|
||||
LET es_prod = 0
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# REPUESTOS -> costo estandard irtb00013.costo_st
|
||||
#-------------------------------------------------------------------------
|
||||
IF ptipoInv = 'R' THEN
|
||||
LET qsql =
|
||||
"SELECT ISNULL(a.costo_st,0)
|
||||
FROM marmotech.dbo.irtb00013 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 sc_rep FROM qsql
|
||||
EXECUTE sc_rep INTO costo
|
||||
USING pcod_n, pcod_grupo, pcod_tipo, pcod_sec, pfecha
|
||||
FREE sc_rep
|
||||
IF costo IS NULL THEN
|
||||
LET costo = 0
|
||||
END IF
|
||||
RETURN costo
|
||||
END IF
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# TERMINADOS -> costo estandard iptb00004 (material + labor + gastos)
|
||||
# Se calcula siempre porque es el respaldo y el valor para es_produccion.
|
||||
#-------------------------------------------------------------------------
|
||||
LET qsql =
|
||||
"SELECT ISNULL(AVG(ISNULL(a.material,0)+ISNULL(a.labor,0)+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 sc_std FROM qsql
|
||||
EXECUTE sc_std INTO costo_std
|
||||
USING pcod_n, pcod_grupo, pcod_tipo, pcod_sec, pfecha
|
||||
FREE sc_std
|
||||
IF costo_std IS NULL THEN
|
||||
LET costo_std = 0
|
||||
END IF
|
||||
|
||||
# es_produccion del articulo
|
||||
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 sc_esp FROM qsql
|
||||
EXECUTE sc_esp INTO es_prod
|
||||
USING pcod_n, pcod_grupo, pcod_tipo, pcod_sec
|
||||
FREE sc_esp
|
||||
IF es_prod IS NULL THEN
|
||||
LET es_prod = 0
|
||||
END IF
|
||||
|
||||
# Producto de produccion -> siempre estandard
|
||||
IF es_prod = 1 THEN
|
||||
RETURN costo_std
|
||||
END IF
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# COMPRA/VENTA -> ultima liquidacion DEL MES vs existencia
|
||||
#-------------------------------------------------------------------------
|
||||
LET qsql =
|
||||
"SELECT TOP 1 ISNULL(a.costo_lq,0), ISNULL(a.cantidad,0)
|
||||
FROM marmotech.dbo.cttb00013 a
|
||||
WHERE a.cod_n = ? AND a.cod_grupo = ? AND a.cod_tipo = ? AND a.cod_sec = ?
|
||||
AND YEAR(a.fecha_lq) = YEAR(?) AND MONTH(a.fecha_lq) = MONTH(?)
|
||||
AND a.fecha_lq <= ?
|
||||
AND a.status_t IS NULL
|
||||
ORDER BY a.fecha_lq DESC, a.fech_crea DESC"
|
||||
PREPARE sc_lq FROM qsql
|
||||
EXECUTE sc_lq INTO xcosto_lq, cant_lq
|
||||
USING pcod_n, pcod_grupo, pcod_tipo, pcod_sec, pfecha, pfecha, pfecha
|
||||
FREE sc_lq
|
||||
|
||||
# No hay liquidacion en el mes -> estandard
|
||||
IF STATUS = NOTFOUND OR xcosto_lq IS NULL THEN
|
||||
RETURN costo_std
|
||||
END IF
|
||||
|
||||
# Existencia actual del articulo (solo movimientos vigentes)
|
||||
LET qsql =
|
||||
"SELECT ISNULL(SUM(a.cantidad_2),0)
|
||||
FROM marmotech.dbo.iptb00006 a
|
||||
WHERE a.cod_n = ? AND a.cod_grupo = ? AND a.cod_tipo = ? AND a.cod_sec = ?
|
||||
AND a.status_t IS NULL"
|
||||
PREPARE sc_exi FROM qsql
|
||||
EXECUTE sc_exi INTO existencia
|
||||
USING pcod_n, pcod_grupo, pcod_tipo, pcod_sec
|
||||
FREE sc_exi
|
||||
IF existencia IS NULL THEN
|
||||
LET existencia = 0
|
||||
END IF
|
||||
|
||||
# Cantidad liquidada mayor que la existencia -> costo liquidado
|
||||
IF cant_lq > existencia THEN
|
||||
RETURN xcosto_lq
|
||||
END IF
|
||||
|
||||
# Existencia mayor o igual -> costo estandard
|
||||
RETURN costo_std
|
||||
|
||||
END FUNCTION
|
||||
@@ -0,0 +1,19 @@
|
||||
FUNCTION cuentas()
|
||||
DEFINE kcuenta VARCHAR(14),
|
||||
kdescripcion CHAR(60),
|
||||
cuentas ui.ComboBox
|
||||
|
||||
LET cuentas = ui.combobox.forname("formonly.xcuenta")
|
||||
|
||||
DECLARE busca_cuenta CURSOR FOR
|
||||
SELECT RTRIM(a.cuenta_no),RTRIM(a.descripcion)+'('+RTRIM(a.cuenta_no)+')'
|
||||
FROM cgtb00001 a
|
||||
WHERE a.nivel > 2 AND a.cuenta_no LIKE '7%' AND a.status_t IS NULL
|
||||
ORDER BY a.descripcion
|
||||
|
||||
CALL cuentas.clear()
|
||||
FOREACH busca_cuenta INTO kcuenta,kdescripcion
|
||||
CALL cuentas.additem(kcuenta,kdescripcion)
|
||||
END FOREACH
|
||||
|
||||
END FUNCTION
|
||||
@@ -0,0 +1,54 @@
|
||||
FUNCTION busca_departamento()
|
||||
DEFINE pdepartamento ui.combobox,
|
||||
kdepartamento SMALLINT,kdescripcion CHAR(30)
|
||||
|
||||
LET pdepartamento = ui.combobox.forname("formonly.departamento")
|
||||
CALL pdepartamento.clear()
|
||||
DECLARE pagar CURSOR FOR
|
||||
SELECT departamento, nom_dpto FROM adtb00001
|
||||
WHERE status_t is null
|
||||
ORDER BY nom_dpto
|
||||
FOREACH pagar INTO kdepartamento,kdescripcion
|
||||
CALL pdepartamento.additem(kdepartamento,kdescripcion)
|
||||
END FOREACH
|
||||
|
||||
END FUNCTION
|
||||
{
|
||||
FUNCTION departamento_user()
|
||||
DEFINE departamentos_user DYNAMIC ARRAY OF RECORD
|
||||
departamento INT,
|
||||
titulo VARCHAR(100)
|
||||
END RECORD
|
||||
|
||||
DECLARE busca_dep CURSOR FOR
|
||||
SELECT '0',a.departamento,a.nom_dpto,a.tipo_departamento
|
||||
FROM adtb00001 a WHERE a.status_t IS NULL
|
||||
ORDER BY a.nom_dpto
|
||||
|
||||
|
||||
LET idx = 1
|
||||
FOREACH busca_dep INTO arr_departamentos[idx].*
|
||||
LET idx = idx + 1
|
||||
END FOREACH
|
||||
|
||||
END FUNCTION
|
||||
}
|
||||
|
||||
FUNCTION departamento_user(xuser)
|
||||
DEFINE pdepartamento ui.combobox,
|
||||
kdepartamento SMALLINT,kdescripcion CHAR(30),
|
||||
xuser STRING
|
||||
|
||||
LET pdepartamento = ui.combobox.forname("formonly.departamento")
|
||||
CALL pdepartamento.clear()
|
||||
DECLARE depto CURSOR FOR
|
||||
SELECT a.departamento, a.nom_dpto FROM adtb00001 a,adtb00056 b
|
||||
WHERE a.departamento = b.departamento_visualiza AND
|
||||
b.usuario = xuser AND
|
||||
a.status_t is null
|
||||
ORDER BY nom_dpto
|
||||
FOREACH depto INTO kdepartamento,kdescripcion
|
||||
CALL pdepartamento.additem(kdepartamento,kdescripcion)
|
||||
END FOREACH
|
||||
|
||||
END FUNCTION
|
||||
@@ -0,0 +1,42 @@
|
||||
FUNCTION maquinas(xdepartamento)
|
||||
DEFINE
|
||||
kmaquina VARCHAR(14),
|
||||
kdescripcion CHAR(75),
|
||||
maquinas ui.ComboBox,
|
||||
xdepartamento INT
|
||||
|
||||
LET maquinas = ui.combobox.forname("formonly.codigo")
|
||||
|
||||
IF xdepartamento = -1 THEN
|
||||
DECLARE busca_maquinas1 CURSOR FOR
|
||||
SELECT a.codigo,
|
||||
RTRIM(a.nombre) + '(' + ISNULL(RTRIM(a.codigo_externo), ' ')
|
||||
+ ')'
|
||||
FROM irtb00009 a
|
||||
WHERE a.status_t IS NULL AND a.codigo_externo IS NOT NULL
|
||||
ORDER BY a.nombre
|
||||
|
||||
CALL maquinas.clear()
|
||||
|
||||
FOREACH busca_maquinas1 INTO kmaquina, kdescripcion
|
||||
CALL maquinas.additem(kmaquina, kdescripcion)
|
||||
END FOREACH
|
||||
ELSE
|
||||
|
||||
DECLARE busca_maquinas2 CURSOR FOR
|
||||
SELECT a.codigo,
|
||||
RTRIM(a.nombre) + '(' + ISNULL(RTRIM(a.codigo_externo), ' ')
|
||||
+ ')'
|
||||
FROM irtb00009 a
|
||||
WHERE a.status_t IS NULL AND a.departamento = xdepartamento
|
||||
AND a.codigo_externo IS NOT NULL
|
||||
ORDER BY a.nombre
|
||||
|
||||
CALL maquinas.clear()
|
||||
FOREACH busca_maquinas2 INTO kmaquina, kdescripcion
|
||||
CALL maquinas.additem(kmaquina, kdescripcion)
|
||||
END FOREACH
|
||||
|
||||
END IF
|
||||
|
||||
END FUNCTION
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
FUNCION : msgmodal
|
||||
OBJETIVO : Mostrar un mensaje de msgtable en una ventana MODAL.
|
||||
Complementa a msg(), que lo despliega en la linea de ERROR.
|
||||
DESARROLLADO : Equipo Tecnologia (Juan Soto)
|
||||
FECHA : 21 Septiembre 2026
|
||||
|
||||
CUANDO USAR CUAL
|
||||
----------------
|
||||
msg(n) -> Errores de VALIDACION durante la captura. El usuario esta
|
||||
parado en el campo, lee el aviso en la linea de ERROR,
|
||||
corrige y sigue. No interrumpe el flujo.
|
||||
|
||||
msgmodal(n) -> Hechos que el usuario NO PUEDE pasar por alto, tipicamente
|
||||
cuando se ABORTO la transaccion y el documento NO se guardo.
|
||||
Si eso solo parpadeara en la linea de ERROR mientras la
|
||||
pantalla se limpia, el usuario se iria creyendo que guardo.
|
||||
|
||||
El texto vive en msgtable igual que el de msg(), de modo que se puede
|
||||
corregir sin recompilar los programas.
|
||||
}
|
||||
|
||||
FUNCTION msgmodal(numero_msg)
|
||||
DEFINE
|
||||
numero_msg SMALLINT,
|
||||
descripcion CHAR(120)
|
||||
|
||||
LET descripcion = NULL
|
||||
|
||||
SELECT desc_msg
|
||||
INTO descripcion
|
||||
FROM msgtable
|
||||
WHERE cod_msg = numero_msg
|
||||
|
||||
IF status = NOTFOUND OR descripcion IS NULL THEN
|
||||
LET descripcion = "MENSAJE NO DEFINIDO EN MSGTABLE: ",
|
||||
numero_msg USING "<<<<"
|
||||
END IF
|
||||
|
||||
CALL fgl_winmessage("AVISO", descripcion CLIPPED, "stop")
|
||||
|
||||
END FUNCTION
|
||||
@@ -0,0 +1,45 @@
|
||||
FUNCTION productos_incluye(tabla1,tabla2,tabla3,tabla4,tabla5,xcriterio,xbodega,xfecha,xseccion,xtramo)
|
||||
DEFINE tabla1,tabla2,tabla3,tabla4,tabla5,selec,xcriterio STRING,
|
||||
xbodega,xseccion,xtramo SMALLINT,
|
||||
xfecha DATE,
|
||||
xid INT,
|
||||
xfech_crea DATETIME YEAR TO MINUTE
|
||||
DEFINE xitems RECORD
|
||||
cod_n SMALLINT,
|
||||
cod_grupo SMALLINT,
|
||||
cod_tipo SMALLINT,
|
||||
cod_sec SMALLINT
|
||||
END RECORD
|
||||
|
||||
LET xfech_crea = CURRENT
|
||||
LET selec = "SELECT DISTINCT a.cod_n,a.cod_Grupo,a.cod_tipo,a.cod_sec FROM ",tabla1 CLIPPED," AS a ",
|
||||
" INNER JOIN ",tabla5 CLIPPED ," AS b ON a.cod_n = b.cod_n AND a.cod_grupo = b.cod_grupo AND ",
|
||||
" a.cod_tipo = b.cod_tipo AND ",
|
||||
" a.cod_sec = b.cod_sec AND a.status_t IS NULL AND b.status_t is NULL AND a.control_existencia = 'SI' ",
|
||||
" WHERE b.bodega = ",xbodega USING "<<<", " and ",xcriterio CLIPPED
|
||||
|
||||
PREPARE comando FROM selec
|
||||
DECLARE busca_item CURSOR FOR comando
|
||||
|
||||
LET selec = "SELECT DISTINCT a.cod_n FROM ",tabla3 CLIPPED,
|
||||
" AS a WHERE a.cod_n = ? AND a.cod_grupo = ? AND a.cod_tipo = ? AND a.cod_sec = ? AND a.fecha = ? AND a.bodega = ?"
|
||||
PREPARE comando1 FROM selec
|
||||
|
||||
LET selec = "INSERT INTO ",tabla3 CLIPPED," (idtrx,fecha,bodega,cod_Seccion,cod_tramo,cod_n,cod_grupo,cod_tipo,cod_Sec,cantidad,us_crea,fech_crea) ",
|
||||
" VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"
|
||||
PREPARE inserta FROM selec
|
||||
|
||||
LET selec = "SELECT MAX(a.idtrx) FROM ",tabla3 CLIPPED, " AS a WHERE a.fecha =? AND a.bodega =? "
|
||||
PREPARE busca_max FROM selec
|
||||
EXECUTE busca_max INTO xid USING xfecha,xbodega
|
||||
|
||||
FOREACH busca_item INTO xitems.*
|
||||
EXECUTE comando1 USING xitems.cod_n,xitems.cod_grupo,xitems.cod_tipo,xitems.cod_sec,xfecha,xbodega
|
||||
|
||||
IF STATUS = NOTFOUND THEN
|
||||
EXECUTE inserta USING xid,xfecha,xbodega,xseccion,xtramo,xitems.cod_n,xitems.cod_grupo,xitems.cod_tipo,
|
||||
xitems.cod_sec,"0","INCLUYE",xfech_crea
|
||||
LET xid = xid + 1
|
||||
END IF
|
||||
END FOREACH
|
||||
END FUNCTION
|
||||
@@ -0,0 +1,17 @@
|
||||
FUNCTION cseccion(almacen)
|
||||
DEFINE kcod_seccion,almacen SMALLINT,
|
||||
kdescripcion CHAR(30),
|
||||
pseccion ui.ComboBox
|
||||
|
||||
LET pseccion = ui.combobox.forname("formonly.seccion")
|
||||
|
||||
DECLARE busca_sec CURSOR FOR
|
||||
SELECT a.cod_seccion,a.descripcion FROM Intb00010 a
|
||||
WHERE a.cod_bodega = almacen
|
||||
|
||||
CALL pseccion.clear()
|
||||
FOREACH busca_sec INTO kcod_seccion,kdescripcion
|
||||
CALL pseccion.additem(kcod_seccion,kdescripcion)
|
||||
END FOREACH
|
||||
CALL pseccion.additem(99,"TODAS")
|
||||
END FUNCTION
|
||||
@@ -0,0 +1,18 @@
|
||||
|
||||
FUNCTION ctramo(almacen,seccion)
|
||||
DEFINE kcod_tramo,almacen,seccion SMALLINT,kdescripcion CHAR(30),
|
||||
ptramo ui.ComboBox
|
||||
|
||||
LET ptramo = ui.combobox.forname("formonly.tramo")
|
||||
|
||||
DECLARE busca_tramo CURSOR FOR
|
||||
SELECT a.cod_tramo,a.descripcion FROM Intb00043 a
|
||||
WHERE a.cod_bodega = almacen and a.cod_Seccion = seccion
|
||||
|
||||
CALL ptramo.clear()
|
||||
FOREACH busca_tramo INTO kcod_tramo,kdescripcion
|
||||
DISPLAY "tramos ",kcod_tramo,kdescripcion," ",almacen," ",seccion
|
||||
CALL ptramo.additem(kcod_tramo,kdescripcion)
|
||||
END FOREACH
|
||||
CALL ptramo.additem(99,"TODOS")
|
||||
END FUNCTION
|
||||
Reference in New Issue
Block a user