7- ABC模型之分摊(实现)

分摊:就是对成本的摊销过程,依据动因占比进行分摊。分摊过程是有过程依赖的,即需要做完 RR 分摊才能做 RA,RO 分摊。如下图是一个正规的分摊过程。不过我们的案例省掉了 RO 分摊过程。

在上图中,大家需要理解几个字母的意思。

R :资源(成本)

A :作业(生产过程的流程作业)

O :对象(企业的产品或服务)

RR 分摊:就是资源到资源的分摊过程,一般是为了区分在同一网点同一资源下,服务不同的作业,比如像营业点的人工成本,即可以做收件,又可以做派件,所以在资源端先把收件的作业和派件的作业成本区分开来。

RA 分摊:资源到作业的分摊过程。把成本与作业建立关系。计算出作业消耗的成本。

AA 分摊:对作业的一个细分过程,在有些作业比较粗时,需要再细分下。

AO 分摊:作业到对象的分摊,对这个作业消耗的成本分摊到他服务的对象上。

RO 分摊:资源到对象的分摊,针对某类资源服务指定的对象时,用此分摊。

此部份主要都是程序实现,我贴一份脚本讲解下,其他可以见:

https://github.com/blt328/abc_blt

RR 分摊程序脚本:

create or replace procedure p_abc_fct_rr_dist(p_to_dt date default sysdate ) is

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

   author  : blt

   created : 2019-06-30

   purpose :

   version  modify  time        desc

   -------  -----   ----------  -------------------------------

   v1.0     blt     2019-06-30  生成 RR 分摊结果

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

 

  v_sqlstate  varchar2 ( 1000 );

  v_proc_name varchar2 ( 300 );

  -- 自定义变量

  v_fm_date date ;

  v_to_date date ;

  v_month   varchar2 ( 10 );

begin

  v_sqlstate  := ' 变量赋值 ' ;

  v_proc_name := 'p_abc_fct_rr_dist' ;

  v_fm_date   := trunc(add_months(p_to_dt, - 1 ), 'MM' );

  v_to_date   := trunc(p_to_dt, 'MM' );

  v_month     := to_char(v_fm_date, 'YYYYMM' );

 

  v_sqlstate := ' 删除数据 ' ;

  delete abc_fct_rr_dist_tmp01;

  delete abc_fct_rr_dist_tmp02;

  delete abc_fct_rr_dist_tmp03;

  delete abc_fct_rr_dist a where a.month_code = v_month;

 

  v_sqlstate := ' 建立分摊标准 ' ;

  insert into abc_fct_rr_dist_tmp01

    select b.mode_code,

           a.dept_code         fm_dept_code,

           a.dept_name         fm_dept_name,

           b.fm_dept_type_code,

           b.fm_dept_type_name,

           b.fm_func_code,

           b.fm_func_name,

           b.fm_reso_code,

           b.fm_reso_name,

           a.dept_code         to_dept_code,

           a.dept_name         to_dept_name,

           b.to_dept_type_code,

           b.to_dept_type_name,

           b.to_func_code,

           b.to_func_name,

           b.to_reso_code,

           b.to_reso_name,

           b.dist_type,

           b.driv_code,

           b.driv_name

      from abc_dim_dept a

     inner join abc_rel_rr_dist b

        on a.dept_type = b.fm_dept_type_code

       and b.fm_dt <= v_fm_date

       and b.to_dt >= v_fm_date

     where a.fm_tm <= v_fm_date

       and a.to_tm >= v_fm_date;

 

  v_sqlstate := ' 关联资源 ' ;

  insert into abc_fct_rr_dist_tmp02

    select a.mode_code,

           a.fm_dept_code,

           a.fm_dept_name,

           a.fm_dept_type_code,

           a.fm_dept_type_name,

           a.fm_func_code,

           a.fm_func_name,

           a.fm_reso_code,

           a.fm_reso_name,

           b.car_no            fm_car,

           b.amt               fm_amt,

           a.to_dept_code,

           a.to_dept_name,

           a.to_dept_type_code,

           a.to_dept_type_name,

           a.to_func_code,

           a.to_func_name,

           a.to_reso_code,

           a.to_reso_name,

           a.dist_type,

           a.driv_code,

           a.driv_name

      from abc_fct_rr_dist_tmp01 a

      left join abc_fct_reso_list b

        on a.fm_dept_code = b.dept_code

       and a.fm_func_code = b.func_code

       and a.fm_reso_code = b.reso_code

       and b.month_code = v_month;

 

  v_sqlstate := ' 关联动因 ' ;

  insert into abc_fct_rr_dist_tmp03

    select a.mode_code,

           a.fm_dept_code,

           a.fm_dept_name,

           a.fm_dept_type_code,

           a.fm_dept_type_name,

           a.fm_func_code,

           a.fm_func_name,

           a.fm_reso_code,

           a.fm_reso_name,

           a.fm_car,

           a.fm_amt,

           a.to_dept_code,

           a.to_dept_name,

           a.to_dept_type_code,

           a.to_dept_type_name,

           a.to_func_code,

           a.to_func_name,

           a.to_reso_code,

           a.to_reso_name,

           a.dist_type,

           a.driv_code,

           a.driv_name,

           b.qty,

           sum (b.qty) over( partition by a.fm_dept_code, a.fm_func_code, a.fm_reso_code, a.fm_car) all_qty

      from abc_fct_rr_dist_tmp02 a

      left join abc_fct_rr_driv b

        on a.to_dept_code = b.dept_code

       and a.to_func_code = b.func_code

       and a.driv_code = b.driv_code

       and b.month_code = v_month;

 

  v_sqlstate := ' 生成分摊结果 ' ;

  insert into abc_fct_rr_dist

    select a.mode_code,

           v_month month_code,

           a.fm_dept_code,

           a.fm_dept_name,

           a.fm_dept_type_code,

           a.fm_dept_type_name,

           a.fm_func_code,

           a.fm_func_name,

           a.fm_reso_code,

           a.fm_reso_name,

           a.fm_car,

           a.fm_amt,

           a.to_dept_code,

           a.to_dept_name,

           a.to_dept_type_code,

           a.to_dept_type_name,

           a.to_func_code,

           a.to_func_name,

           a.to_reso_code,

           a.to_reso_name,

           a.dist_type,

           a.driv_code,

           a.driv_name,

           a.qty,

           a.all_qty,

           case

             when a.driv_code in ( 'RR001' , 'RA001' , 'AA001' , 'AO001' ) then

              a.fm_amt

             else

              a.fm_amt * a.qty / a.all_qty

           end to_amt,

           sysdate load_tm

      from abc_fct_rr_dist_tmp03 a;

  commit ;

  v_sqlstate := ' 结束 ' ;

 

exception

  when others then

    rollback ;

    commit ;

 

end p_abc_fct_rr_dist;


更多技术文章请关注公众号 BLT328( 长按后点识别图中二维码 ):

请使用浏览器的分享功能分享到微信等