lunes, 30 de julio de 2018

Function for Depreciation of Imported Assets


/*********************************************************************************/

-- select * from fnt_migrar_depreciacion();

-- drop function fnt_migrar_depreciacion();

create or replace function fnt_migrar_depreciacion()
returns table
(
    codigo_activo_ varchar,
    anio_ubicacion_ date,
    costo_adquisicion_ numeric(20,2),
    depreciacion_mensual_ numeric(20,2),
    depreciacion_acumulado_ numeric(20,2),
    valor_libro_ numeric(20,2),
    fecha_inicial_ date,
    cantidad_anios_ int,
    cantidad_meses_ int,
    num_periodo_ int,
    periodo_depreciacion_ date,
    estado_periodo_ char(2),
    resultado_depreciacion_ varchar
)
as $$
declare
    v_cantidad_meses int = 0;
    v_cantidad_anios int = 0;
    v_periodo_inicial date;
    asset_counter int = 0;
    dep_counter int = 0;
    v_depreciacion_mensual numeric(20,2) = 0.00;
    v_depreciacion_acum numeric(20,2) = 0.00;
    v_num_periodo int = 0;
    v_periodo_depreciacion date;
    v_estado_periodo char(2) = 'DR';
    v_monto_acumulado numeric(20,2) = 0.00;
    v_resultado_depreciacion varchar;
  
    v_cadena_depreciacion varchar;
    v_cadena_acumulado varchar;
  
    k record;
  
    c cursor for
    select
        t.codigo_activo,
        t.anio_ubicacion,
        t.costo_adquisicion,
        t.depreciacion_mensual,
        t.depreciacion_acumulado,
        t.valor_libro
    from tmp_activos as t
    order by
        t.num_categoria,
        t.codigo_activo;
begin
    drop table if exists tmp_assets;
  
    create temporary table tmp_assets
    (
        codigo_activo varchar,
        anio_ubicacion date,
        costo_adquisicion numeric(20,2),
        depreciacion_mensual numeric(20,2),
        depreciacion_acumulado numeric(20,2),
        valor_libro numeric(20,2),
        fecha_inicial date,
        cantidad_anios int,
        cantidad_meses int,
        num_periodo int,
        periodo_depreciacion date,
        estado_periodo char(2),
        resultado_depreciacion varchar
    );
  
    open c;
  
    fetch c into k;
  
    while (found) loop
        -- raise notice ' PROCESANDO % ', k.codigo_activo;
      
        v_periodo_inicial = k.anio_ubicacion::date+'1 month'::interval;
        v_cantidad_meses = case when k.depreciacion_mensual > 0 then (k.costo_adquisicion / k.depreciacion_mensual) else 0 end;
        v_cantidad_anios = (v_cantidad_meses / 12)::int;
  
        v_periodo_depreciacion = v_periodo_inicial;
        v_depreciacion_mensual = k.depreciacion_mensual;
      
        for dep_counter in 1..v_cantidad_meses loop
            if (dep_counter = v_cantidad_meses) then
                -- raise notice ' CODIGO=%, PERIODO=%, DEPRECIACION=%, COSTO=%', k.codigo_activo, dep_counter, (k.costo_adquisicion - v_depreciacion_acum), k.costo_adquisicion;
              
                v_num_periodo = dep_counter;
              
                v_periodo_depreciacion = v_periodo_depreciacion::date+'1 month'::interval;
              
                v_estado_periodo =
                case
                    when v_periodo_depreciacion between v_periodo_inicial and now()::date then
                        'CO'
                    else
                        'DR'
                end;
          
                v_depreciacion_mensual = v_depreciacion_mensual + (k.costo_adquisicion - (v_depreciacion_acum + v_depreciacion_mensual));
                v_depreciacion_acum = v_depreciacion_acum + v_depreciacion_mensual;
          
                v_resultado_depreciacion = fnt_describir_depreciacion(v_monto_acumulado, v_depreciacion_mensual);
              
                insert into tmp_assets
                (
                    codigo_activo,
                    anio_ubicacion,
                    costo_adquisicion,
                    depreciacion_mensual,
                    depreciacion_acumulado,
                    valor_libro,
                    fecha_inicial,
                    cantidad_anios,
                    cantidad_meses,
                    num_periodo,
                    periodo_depreciacion,
                    estado_periodo,
                    resultado_depreciacion
                )
                select
                    k.codigo_activo,
                    k.anio_ubicacion,
                    k.costo_adquisicion,
                    v_depreciacion_mensual,
                    v_depreciacion_acum,
                    (k.costo_adquisicion - v_depreciacion_acum)::numeric(20,2) as valor_libro,
                    v_periodo_inicial as fecha_inicial,
                    v_cantidad_anios,
                    v_cantidad_meses,
                    v_num_periodo,
                    v_periodo_depreciacion,
                    v_estado_periodo,
                    v_resultado_depreciacion;
              
                v_monto_acumulado = v_monto_acumulado + v_depreciacion_mensual;
            else
                -- raise notice ' CODIGO=%, PERIODO=% DEPRECIACION=%, COSTO=%', k.codigo_activo, dep_counter, k.depreciacion_mensual, k.costo_adquisicion;
              
                v_num_periodo = dep_counter;
              
                v_periodo_depreciacion = v_periodo_depreciacion::date+'1 month'::interval;
              
                v_estado_periodo =
                case
                    when v_periodo_depreciacion between v_periodo_inicial and now()::date then
                        'CO'
                    else
                        'DR'
                end;
              
                v_depreciacion_acum = v_depreciacion_acum + v_depreciacion_mensual;
          
                v_resultado_depreciacion = fnt_describir_depreciacion(v_monto_acumulado, v_depreciacion_mensual);  
          
                insert into tmp_assets
                (
                    codigo_activo,
                    anio_ubicacion,
                    costo_adquisicion,
                    depreciacion_mensual,
                    depreciacion_acumulado,
                    valor_libro,
                    fecha_inicial,
                    cantidad_anios,
                    cantidad_meses,
                    num_periodo,
                    periodo_depreciacion,
                    estado_periodo,
                    resultado_depreciacion
                )
                select
                    k.codigo_activo,
                    k.anio_ubicacion,
                    k.costo_adquisicion,
                    k.depreciacion_mensual,
                    v_depreciacion_acum,
                    (k.costo_adquisicion - v_depreciacion_acum)::numeric(20,2) as valor_libro,
                    v_periodo_inicial as fecha_inicial,
                    v_cantidad_anios,
                    v_cantidad_meses,
                    v_num_periodo,
                    v_periodo_depreciacion,
                    v_estado_periodo,
                    v_resultado_depreciacion;
              
                v_monto_acumulado = v_monto_acumulado + v_depreciacion_mensual;
            end if;
          
            dep_counter = dep_counter + 1;
        end loop;
      
        fetch c into k;
  
        v_depreciacion_acum = 0.00;
        asset_counter = asset_counter + 1;
    end loop;
  
    close c;
  
    return query
    (
        select
            t.codigo_activo,
            t.anio_ubicacion,
            t.costo_adquisicion,
            t.depreciacion_mensual,
            t.depreciacion_acumulado,
            t.valor_libro,
            t.fecha_inicial,
            t.cantidad_anios,
            t.cantidad_meses,
            t.num_periodo,
            t.periodo_depreciacion,
            t.estado_periodo,
            t.resultado_depreciacion
        from tmp_assets as t
    );
end;
$$ language plpgsql;

/*********************************************************************************/

-- select * from fnt_describir_depreciacion(0.00, 4259.07);

create or replace function fnt_describir_depreciacion(p_acumulado numeric(20,2), p_depreciacion numeric(20,2))
returns varchar
as $$
declare
    v_cadena_acumulado varchar;
    v_cadena_depreciacion varchar;
    v_cadena_resultado varchar;
begin
    v_cadena_acumulado = p_acumulado::varchar;
    v_cadena_depreciacion = p_depreciacion::varchar;
    v_cadena_resultado = (p_acumulado + p_depreciacion)::varchar;
   
    return
    (
        v_cadena_acumulado || '|' || v_cadena_acumulado || ' + ' ||
        v_cadena_depreciacion || '|' || v_cadena_depreciacion || ' = ' ||
        v_cadena_resultado || '|' || v_cadena_resultado
    );
end;
$$ language plpgsql;

/*********************************************************************************/

No hay comentarios:

Publicar un comentario