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(長按後點識別圖中二維碼):

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章