Ejemplo de lineas de procedimiento almacenado en
PostgreSQL
(desarrollo de Fernando San Martin Woerner) |
|
drop function f_centraliza_factura (integer); CREATE FUNCTION f_centraliza_factura (integer) RETURNS integer AS ' DECLARE cod_documento ALIAS FOR $1; registros RECORD; rdetalle RECORD; rtrans RECORD; rpagos RECORD; rmoneda RECORD; rmontos RECORD; mdebe numeric(18,6); mhaber numeric(18,6); diferencia numeric(18,6); cod_transaccion varchar(10); ctacble varchar(20); pitemconcepto integer; BEGIN cod_transaccion := ''007''; SELECT INTO rtrans MAX(numdocumento) AS maxdoc FROM tmi_cabeceradocumentos WHERE codtipotransaccion = cod_transaccion; IF rtrans.maxdoc IS NULL THEN rtrans.maxdoc := 0; END IF; DELETE FROM tmi_cabeceradocumentos WHERE num_documento = cod_documento AND tipo_documento = ''F''; SELECT INTO rmoneda cod_moneda FROM tmi_moneda; FOR registros IN SELECT f.fecha_factura , f.num_factura , cl.rut_cliente , cl.dir_particular_cliente , cl.nom_cliente , round(f.valor_factura * f.valor_uf) as valor_factura , cc.num_cuenta_contable_i , f.valor_uf , td.cod_docto_contable , c.cod_contrato , c.cod_proyecto FROM factura f , contrato c , cliente cl , centro_costo cc , tipo_documento td WHERE f.cod_contrato = c.cod_contrato AND c.rut_cliente = cl.rut_cliente AND c.cod_proyecto = cc.cod_proyecto AND c.cod_etapa = cc.cod_etapa AND f.num_factura = cod_documento AND td.cod_tipo_documento = 1 LOOP rtrans.maxdoc := rtrans.maxdoc + 1; INSERT INTO tmi_cabeceradocumentos ( codtipotransaccion , numdocumento , codestadodocumento , foliodocumento , fechadocumento , coddoctocontable , rutpersona , direccionpersona , tipopersona , nombrespersona , escliente , esproveedor , esempleado , estacentralizado , tipo_documento , num_documento ) values ( cod_transaccion, rtrans.maxdoc, ''N'', registros.num_factura, registros.fecha_factura, registros.cod_docto_contable, registros.rut_cliente, registros.dir_particular_cliente, ''N'', registros.nom_cliente, ''S'', ''S'', ''N'', ''N'', ''F'', registros.num_factura ); FOR rdetalle IN SELECT codconcepto, codtipoimputacion, sedistribuye, numcuentacontable FROM tmi_definiciontransaccion WHERE codtipotransaccion = cod_transaccion LOOP IF rdetalle.codconcepto = 1 THEN INSERT INTO tmi_detalleconceptos ( codtipotransaccion , numdocumento , codconcepto , itemconcepto , numctacontable , monto , glosalineal , codmoneda , paridadmoneda , coddoctocbleref , numdoctoref , fechadoctoref ) VALUES ( cod_transaccion, rtrans.maxdoc, rdetalle.codconcepto, 1, registros.num_cuenta_contable_i, registros.valor_factura, ''FACTURA '' || registros.num_factura, rmoneda.cod_moneda, 1, registros.cod_docto_contable, registros.num_factura, registros.fecha_factura ); ELSE pitemconcepto := 0; FOR rpagos IN SELECT p.monto_contrato * registros.valor_uf as valor , ti.cod_doctocontable , tp.num_cuenta_contable_d from pago_contrato p , tipo_pago_ingreso tpi , tipo_ingreso ti , tmi_proyecto_tipo_ingreso tp where p.cod_tipo_pago = tpi.cod_tipo_pago and tpi.cod_tipo_ingreso = ti.cod_tipo_ingreso and ti.cod_tipo_ingreso = tp.cod_tipo_ingreso and tp.cod_proyecto = registros.cod_proyecto and p.cod_contrato = registros.cod_contrato and ti.cod_tipo_ingreso <= 4 LOOP pitemconcepto := pitemconcepto + 1; INSERT INTO tmi_detalleconceptos ( codtipotransaccion , numdocumento , codconcepto , itemconcepto , numctacontable , monto , glosalineal , codmoneda , paridadmoneda , coddoctocbleref , numdoctoref , fechadoctoref ) VALUES ( cod_transaccion, rtrans.maxdoc, rdetalle.codconcepto, pitemconcepto, rpagos.num_cuenta_contable_d, ROUND(rpagos.valor), ''FACTURA '' || registros.num_factura, rmoneda.cod_moneda, 1, rpagos.cod_doctocontable, registros.num_factura, registros.fecha_factura ); END LOOP; END IF; END LOOP; END LOOP; SELECT INTO rmontos SUM(monto) as total FROM tmi_detalleconceptos WHERE codconcepto = 1 AND numdocumento = rtrans.maxdoc AND codtipotransaccion = ''007''; mdebe := rmontos.total; SELECT INTO rmontos SUM(monto) as total FROM tmi_detalleconceptos WHERE codconcepto = 2 AND numdocumento = rtrans.maxdoc AND codtipotransaccion = ''007''; mhaber := rmontos.total; diferencia := abs(mhaber - mdebe); RAISE NOTICE ''% -> DEBE y HABER %, %, la diferencia %'', |