martes, 23 de enero de 2018

Estado de Resultado en ADempiere

Descargar diseño aqui.

-- Function: adempiere.rep_estado_resultado(numeric, numeric, character, character)

-- DROP FUNCTION adempiere.rep_estado_resultado(numeric, numeric, character, character);

CREATE OR REPLACE FUNCTION adempiere.rep_estado_resultado(
    IN id_compania numeric,
    IN id_periodo numeric,
    IN es_cierre_contable character,
    IN es_periodo_ajuste character)
  RETURNS TABLE(nombre_compania character varying, id_tipo_cuenta character, tipo_cuenta character varying, id_naturaleza character, id_cuenta_mayor numeric, cod_cuenta_mayor numeric, cuenta_mayor character varying, id_cuenta_padre numeric, cod_cuenta_padre numeric, cuenta_padre character varying, id_cuenta_contable numeric, cod_cuenta_contable character varying, cuenta_contable character varying, orden integer, id_titulo numeric, titulo character varying, id_subtitulo numeric, subtitulo character varying, pre_titulo character varying, pre_subtitulo character varying, saldo numeric, saldo_acum numeric, porc numeric, porc_acum numeric, fecha_ini date, fecha_fin date) AS
$BODY$
declare
    nombre_compania_x varchar(255);

    p_movimientos_totales boolean;
    p_tipo_periodo char;
    p_num_periodo numeric(10,0);
    finicial date;
    ffinal date;
begin
    nombre_compania_x =
    (
        select c.name from ad_client c
        where c.ad_client_id = id_compania
    );

    -- Obtener el tipo de periodo (estandar o ajuste) y el consecutivo de periodo
    select
        p.periodtype,
        p.periodno,
        p.startdate,
        p.enddate
    into
        p_tipo_periodo,
        p_num_periodo,
        finicial,
        ffinal
    from c_period p
    where p.c_period_id = id_periodo;

    drop table if exists tmp_cuentas_estado;

    create temporary table tmp_cuentas_estado as
    select
        u.accounttype as id_tipo_cuenta_x,
        case u.accounttype
            when 'R' then '01 - INGRESOS'
            when 'E' then '02 - EGRESOS'
            else ''
        end::varchar as tipo_cuenta_x,
        u.nat as id_naturaleza_x,
        u.ctamayor_id as id_cuenta_mayor_x,
        u.ctmayor_value as cod_cuenta_mayor_x,
        u.ctmayor_name as cuenta_mayor_x,
        u.parent_id as id_cuenta_padre_x,
        u.parent_value as cod_cuenta_padre_x,
        u.parent_name as cuenta_padre_x,
        u.c_elementvalue_id as id_cuenta_contable_x,
        u.value as cod_cuenta_contable_x,
        u.name as cuenta_contable_x,
        ce.orden as orden_x,
        te.nic_titulo_estado_id as id_titulo_x,
        te.name as titulo_x,
        se.nic_subtitulo_estado_id::numeric(10,0) as id_subtitulo_x,
        se.name as subtitulo_x,
        coalesce(te.prefijo, '') as pre_titulo_x,
        coalesce(se.prefijo, '') as pre_subtitulo_x
    from usr_v_vcc u
        join nic_cuentas_estado ce
        on ce.account_id = u.parent_id
        join nic_titulo_estado te
        on ce.nic_titulo_estado_id = te.nic_titulo_estado_id
        join nic_subtitulo_estado se
        on ce.nic_subtitulo_estado_id = se.nic_subtitulo_estado_id
    where u.c_elementvalue_id in
    (
        select distinct sf.id_cuenta from nic_saldos_finales sf
    );

    drop table if exists tmp_movimientos_estado;
   
    create temporary table tmp_movimientos_estado
    (
        tipo_cuenta_x char,
        id_cuenta_contable_x numeric(10,0),
        id_periodo_x numeric(10,0),
        tipo_periodo_x char,
        num_periodo_x numeric(10,0),
        es_cierre_contable_x char,
        es_periodo_ajuste_x char,
        saldo_x numeric(10,2),
        saldo_acum_x numeric(10,2)
    );

    if(es_cierre_contable = 'N')then
        insert into tmp_movimientos_estado
        with cte_movimientos_estado as
        (
            select
                sf.tipo_cuenta as tipo_cuenta_x,
                sf.id_cuenta as id_cuenta_contable_x,
                sf.id_periodo as id_periodo_x,
                sf.tipo_periodo as tipo_periodo_x,
                sf.num_periodo as num_periodo_x,
                sf.es_cierre_contable as es_cierre_contable_x,
                sf.es_periodo_ajuste as es_periodo_ajuste_x,
                sum(coalesce(sf.credito_final, 0.00) - coalesce(sf.debito_final, 0.00))::numeric(10,2) as saldo_x,
                0.00::numeric(10,2) as saldo_acum_x
            from nic_saldos_finales sf
            where sf.tipo_cuenta in ('R', 'E') -- Ingresos y Gastos (Estado de Resultado)
                and sf.tipo_periodo = p_tipo_periodo
                and sf.id_periodo = id_periodo
            group by
                sf.tipo_cuenta,
                sf.id_cuenta,
                sf.id_periodo,
                sf.tipo_periodo,
                sf.num_periodo,
                sf.es_cierre_contable,
                sf.es_periodo_ajuste
            union all
            select
                sf.tipo_cuenta as tipo_cuenta_x,
                sf.id_cuenta as id_cuenta_contable_x,
                sf.id_periodo as id_periodo_x,
                sf.tipo_periodo as tipo_periodo_x,
                sf.num_periodo as num_periodo_x,
                sf.es_cierre_contable as es_cierre_contable_x,
                sf.es_periodo_ajuste as es_periodo_ajuste_x,
                sum(coalesce(sf.credito_final, 0.00) - coalesce(sf.debito_final, 0.00))::numeric(10,2) as saldo_x,
                0.00::numeric(10,2) as saldo_acum_x
            from nic_saldos_finales sf
            where sf.tipo_cuenta in ('R', 'E') -- Ingresos y Gastos (Estado de Resultado)
                and sf.num_periodo =
                    case
                        when es_periodo_ajuste = 'Y' then
                            p_num_periodo - 1
                        else
                            null
                    end
            group by
                sf.tipo_cuenta,
                sf.id_cuenta,
                sf.id_periodo,
                sf.tipo_periodo,
                sf.num_periodo,
                sf.es_cierre_contable,
                sf.es_periodo_ajuste
            union all
            select
                sf.tipo_cuenta as tipo_cuenta_x,
                sf.id_cuenta as id_cuenta_contable_x,
                sf.id_periodo as id_periodo_x,
                sf.tipo_periodo as tipo_periodo_x,
                sf.num_periodo as num_periodo_x,
                sf.es_cierre_contable as es_cierre_contable_x,
                sf.es_periodo_ajuste as es_periodo_ajuste_x,
                0.00::numeric(10,2) as saldo_x,
                sum(coalesce(sf.credito_final, 0.00) - coalesce(sf.debito_final, 0.00))::numeric(10,2) as saldo_acum_x
            from nic_saldos_finales sf
            where sf.tipo_cuenta in ('R', 'E') -- Ingresos y Gastos (Estado de Resultado)
                and sf.num_periodo <= p_num_periodo
            group by
                sf.tipo_cuenta,
                sf.id_cuenta,
                sf.id_periodo,
                sf.tipo_periodo,
                sf.num_periodo,
                sf.es_cierre_contable,
                sf.es_periodo_ajuste
        )
        select
            me.tipo_cuenta_x,
            me.id_cuenta_contable_x,
            me.id_periodo_x,
            me.tipo_periodo_x,
            me.num_periodo_x,
            me.es_cierre_contable_x,
            me.es_periodo_ajuste_x,
            sum(me.saldo_x) as saldo_x,
            sum(me.saldo_acum_x) as saldo_acum_x
        from cte_movimientos_estado me
        group by
            me.tipo_cuenta_x,
            me.id_cuenta_contable_x,
            me.id_periodo_x,
            me.tipo_periodo_x,
            me.num_periodo_x,
            me.es_cierre_contable_x,
            me.es_periodo_ajuste_x,
            me.saldo_x,
            me.saldo_acum_x;
    else
        insert into tmp_movimientos_estado
        with cte_movimientos_estado as
        (
            -- Movimientos contables del período seleccionado
            select
                sf.tipo_cuenta as tipo_cuenta_x,
                sf.id_cuenta as id_cuenta_contable_x,
                sf.id_periodo as id_periodo_x,
                sf.tipo_periodo as tipo_periodo_x,
                sf.num_periodo as num_periodo_x,
                sf.es_cierre_contable as es_cierre_contable_x,
                sf.es_periodo_ajuste as es_periodo_ajuste_x,
                sum(coalesce(sf.credito_final, 0.00) - coalesce(sf.debito_final, 0.00))::numeric(10,2) as saldo_x,
                0.00::numeric(10,2) as saldo_acum_x
            from nic_saldos_finales sf
            where sf.tipo_cuenta in ('R', 'E') -- Ingresos y Gastos (Estado de Resultado)
                and sf.tipo_periodo = p_tipo_periodo
                and sf.id_periodo = id_periodo
            group by
                sf.tipo_cuenta,
                sf.id_cuenta,
                sf.id_periodo,
                sf.tipo_periodo,
                sf.num_periodo,
                sf.es_cierre_contable,
                sf.es_periodo_ajuste
            union all
            -- Movimientos contables acumulados sin cierre y sin ajuste
            select
                sf.tipo_cuenta as tipo_cuenta_x,
                sf.id_cuenta as id_cuenta_contable_x,
                sf.id_periodo as id_periodo_x,
                sf.tipo_periodo as tipo_periodo_x,
                sf.num_periodo as num_periodo_x,
                sf.es_cierre_contable as es_cierre_contable_x,
                sf.es_periodo_ajuste as es_periodo_ajuste_x,
                0.00::numeric(10,2) as saldo_x,
                0.00::numeric(10,2) as saldo_acum_x
            from nic_saldos_finales sf
            where sf.tipo_cuenta in ('R', 'E') -- Ingresos y Gastos (Estado de Resultado)
                and sf.num_periodo <= p_num_periodo
            group by
                sf.tipo_cuenta,
                sf.id_cuenta,
                sf.id_periodo,
                sf.tipo_periodo,
                sf.num_periodo,
                sf.es_cierre_contable,
                sf.es_periodo_ajuste
        )
        select
            me.tipo_cuenta_x,
            me.id_cuenta_contable_x,
            me.id_periodo_x,
            me.tipo_periodo_x,
            me.num_periodo_x,
            me.es_cierre_contable_x,
            me.es_periodo_ajuste_x,
            sum(me.saldo_x) as saldo_x,
            sum(me.saldo_acum_x) as saldo_acum_x
        from cte_movimientos_estado me
        group by
            me.tipo_cuenta_x,
            me.id_cuenta_contable_x,
            me.id_periodo_x,
            me.tipo_periodo_x,
            me.num_periodo_x,
            me.es_cierre_contable_x,
            me.es_periodo_ajuste_x,
            me.saldo_x,
            me.saldo_acum_x;
    end if;

    return query
    (
        with cte_estado_preliminar as
        (
            select
                ce.id_tipo_cuenta_x,
                ce.tipo_cuenta_x,
                ce.id_naturaleza_x,
                ce.id_cuenta_mayor_x,
                ce.cod_cuenta_mayor_x,
                ce.cuenta_mayor_x,
                ce.id_cuenta_padre_x,
                ce.cod_cuenta_padre_x,
                ce.cuenta_padre_x,
                ce.id_cuenta_contable_x,
                ce.cod_cuenta_contable_x,
                ce.cuenta_contable_x,
                ce.orden_x,
                ce.id_titulo_x,
                ce.titulo_x,
                ce.id_subtitulo_x,
                ce.subtitulo_x,
                ce.pre_titulo_x,
                ce.pre_subtitulo_x,
                me.saldo_x,
                me.saldo_acum_x
            from tmp_movimientos_estado me
                join tmp_cuentas_estado ce
                on me.id_cuenta_contable_x = ce.id_cuenta_contable_x
        ),
        cte_estado_resultado as
        (
            select
                er.id_tipo_cuenta_x,
                er.tipo_cuenta_x,
                er.id_naturaleza_x,
                er.id_cuenta_mayor_x,
                er.cod_cuenta_mayor_x,
                er.cuenta_mayor_x,
                er.id_cuenta_padre_x,
                er.cod_cuenta_padre_x,
                er.cuenta_padre_x,
                er.id_cuenta_contable_x,
                er.cod_cuenta_contable_x,
                er.cuenta_contable_x,
                er.orden_x,
                er.id_titulo_x,
                er.titulo_x,
                er.id_subtitulo_x,
                er.subtitulo_x,
                er.pre_titulo_x,
                er.pre_subtitulo_x,
                er.saldo_x,
                er.saldo_acum_x,
                (select sum(er2.saldo_x) from cte_estado_preliminar er2
                where er2.subtitulo_x = er.subtitulo_x) as porc_x,
                (select sum(er2.saldo_acum_x) from cte_estado_preliminar er2
                where er2.subtitulo_x = er.subtitulo_x) as porc_acum_x
            from cte_estado_preliminar er
        ),
        cte_estado_penultimo as
        (
            select
                er.id_tipo_cuenta_x,
                er.tipo_cuenta_x,
                er.id_naturaleza_x,
                er.id_cuenta_mayor_x,
                er.cod_cuenta_mayor_x,
                er.cuenta_mayor_x,
                er.id_cuenta_padre_x,
                er.cod_cuenta_padre_x,
                er.cuenta_padre_x,
                er.id_cuenta_contable_x,
                er.cod_cuenta_contable_x,
                er.cuenta_contable_x,
                er.orden_x,
                er.id_titulo_x,
                er.titulo_x,
                er.id_subtitulo_x,
                er.subtitulo_x,
                er.pre_titulo_x,
                er.pre_subtitulo_x,
                er.saldo_x,
                er.saldo_acum_x,
                case
                    when er.porc_x = 0 then
                        0.00
                    else
                        er.saldo_x / er.porc_x * 100
                end::numeric(18,9) as porc_x,
                case
                    when er.porc_acum_x = 0 then
                        0.00
                    else
                        er.saldo_acum_x / er.porc_acum_x * 100
                end::numeric(18,9) as porc_acum_x
            from cte_estado_resultado er
        ),
        cte_estado_ultimate as
        (
            select
                er.id_tipo_cuenta_x,
                er.tipo_cuenta_x,
                er.id_naturaleza_x,
                er.id_cuenta_mayor_x,
                er.cod_cuenta_mayor_x,
                er.cuenta_mayor_x,
                er.id_cuenta_padre_x,
                er.cod_cuenta_padre_x,
                er.cuenta_padre_x,
                er.id_cuenta_contable_x,
                er.cod_cuenta_contable_x,
                er.cuenta_contable_x,
                er.orden_x,
                er.id_titulo_x,
                er.titulo_x,
                er.id_subtitulo_x,
                er.subtitulo_x,
                er.pre_titulo_x,
                er.pre_subtitulo_x,
                sum(er.saldo_x) as saldo_x,
                sum(er.saldo_acum_x) as saldo_acum_x,
                sum(er.porc_x) as porc_x,
                sum(er.porc_acum_x) as porc_acum_x
            from cte_estado_penultimo er
            group by
                er.id_tipo_cuenta_x,
                er.tipo_cuenta_x,
                er.id_naturaleza_x,
                er.id_cuenta_mayor_x,
                er.cod_cuenta_mayor_x,
                er.cuenta_mayor_x,
                er.id_cuenta_padre_x,
                er.cod_cuenta_padre_x,
                er.cuenta_padre_x,
                er.id_cuenta_contable_x,
                er.cod_cuenta_contable_x,
                er.cuenta_contable_x,
                er.orden_x,
                er.id_titulo_x,
                er.titulo_x,
                er.id_subtitulo_x,
                er.subtitulo_x,
                er.pre_titulo_x,
                er.pre_subtitulo_x
        )
        select
            nombre_compania_x,
            er.id_tipo_cuenta_x,
            er.tipo_cuenta_x,
            er.id_naturaleza_x,
            er.id_cuenta_mayor_x,
            er.cod_cuenta_mayor_x,
            er.cuenta_mayor_x,
            er.id_cuenta_padre_x,
            er.cod_cuenta_padre_x,
            er.cuenta_padre_x,
            er.id_cuenta_contable_x,
            er.cod_cuenta_contable_x,
            er.cuenta_contable_x,
            er.orden_x,
            er.id_titulo_x,
            er.titulo_x,
            er.id_subtitulo_x,
            er.subtitulo_x,
            er.pre_titulo_x,
            er.pre_subtitulo_x,
            er.saldo_x,
            er.saldo_acum_x,
            er.porc_x,
            er.porc_acum_x,
            finicial as fecha_ini_x,
            case
                when es_cierre_contable = 'Y' then
                    (extract(year from ffinal)::varchar || '1231')::date
                when es_periodo_ajuste = 'Y' then
                    (extract(year from ffinal)::varchar || '1231')::date
                else ffinal
            end as fecha_fin_x
        from cte_estado_ultimate er
        where (abs(er.saldo_x) > 0 or abs(er.saldo_acum_x) > 0)
        order by
            er.orden_x,
            er.cuenta_padre_x,
            er.cuenta_mayor_x,
            er.cuenta_contable_x,
            er.cod_cuenta_mayor_x asc
    );
end;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100
  ROWS 1000;

No hay comentarios:

Publicar un comentario