/*
* Автор: Галкин А.И.
* Дата: 2014-04-01
* Задача: http://jira.softage.ru/jira/browse/SDFO-279
* Назначение: Удаление OKSMT2AC
* Изменяются объекты:
		drop table OKSMT2AC
        update package PKG_ANALYTIC
*/

/*
  ****** Инструкции для SQLPlus (обязательно) ******
  Для печати сообщений:
  DBMS_OUTPUT.put_line('<Message>');
*/
whenever sqlerror exit 1;
set serveroutput on;
set echo off;

declare
	filename      varchar2(256) := 'sfm.database-update.2014-04-01.DropOKSMT2AC.sql';
	purpose       varchar2(4000) := 'Удаление OKSMT2AC';
	script_exists number := 0;
begin

	--delete from DB_Update_History where script_name = filename;	commit;
	select count(*)
		into script_exists
		from DB_Update_History
	 where script_name = filename;

	if (script_exists > 0) then
		RAISE_APPLICATION_ERROR(-20001, '"' || filename || '" уже присутствует в базе');
	else
		insert into DB_Update_History
			(script_name, purpose)
		values
			(filename, purpose);
	end if;

	/*
	****** Begin update script ******
	*/
		-- Транзакционный апдейт
		-- execute immediate '';
	/*
	****** End update script ******
	*/
	commit;

exception
	when others then
		rollback;
		raise;
end;
/

DECLARE
   v_column_exists   NUMBER := 0;
BEGIN
   SELECT COUNT (*)
     INTO v_column_exists
     FROM USER_TABLES ut
     WHERE ut.table_name = 'OKSMT2AC';

   IF (v_column_exists > 0)
   THEN
      EXECUTE IMMEDIATE
         'drop table OKSMT2AC';
   END IF;
END;

/

CREATE OR REPLACE PACKAGE BODY KFM."PKG_ANALYTIC" as

  --GetAnalyticCodesInfo
  function GetAnalyticCodesInfo(pAnalyticType  in number,
                                pCodesListType in NUMBER,
                                pResCursor     out sys_refcursor) --версия справочника
   return number is
    Result number default 0;
    vlang  varchar2(10 char) default 'Russian';
    --  isenabled   boolean default true;
  begin
    vlang := pkg_main.GetUserLangSettings;
    case pCodesListType
      when 1 then
        open pResCursor for
          select analyticcode,
                 decode(vlang, 'Kazakh', shortname_kz, shortname) as shortname,
                 decode(vlang, 'Kazakh', analyticname_kz, analyticname) as analyticname,
                 relationcode1,
                 1 as isenabled
            from analyticcodes
           where analytictype = pAnalyticType
             and altermode != -1
           order by analyticcode;
      when 2 then
        open pResCursor for
          select analyticcode,
                 decode(vlang, 'Kazakh', shortname_kz, shortname) as shortname,
                 decode(vlang, 'Kazakh', analyticname_kz, analyticname) as analyticname,
                 relationcode1,
                 decode(altermode, -1, 0, 1) as isenabled
            from analyticcodes
           where analytictype = pAnalyticType
           order by analyticcode;
      when 0 then
        open pResCursor for
          select analyticcode,
                 decode(vlang, 'Kazakh', shortname_kz, shortname) as shortname,
                 decode(vlang, 'Kazakh', analyticname_kz, analyticname) as analyticname,
                 relationcode1,
                 0 as isenabled
            from analyticcodes
           where analytictype = pAnalyticType
             and altermode = -1
           order by analyticcode;

    end case;
    return Result;
  exception
    when others then
      pkg_exceptions.AddException(sqlcode,
                                  sqlerrm,
                                  'pkg_analytic.GetAnalyticCodesInfo');
      Result := -1; --Общая ошибка
      return Result;
  end GetAnalyticCodesInfo;

  --GetAnalyticTypesInfo
  function GetAnalyticTypesInfo(pTypesListType in NUMBER,
                                pResCursor     out sys_refcursor)
    return number is
    Result number default 0;
  begin
    case pTypesListType
      when 1 then
        open pResCursor for
          select analytictype,
                 analyticname,
                 relationtype1 as "RelationCode1"
            from analytictypes
           where altermode != -1
             and visibleforusers = 1
           order by analyticname;
      when 2 then
        open pResCursor for
          select analytictype,
                 analyticname,
                 relationtype1 as "RelationCode1"
            from analytictypes
           where visibleforusers = 1
           order by analyticname;
      when 0 then
        open pResCursor for
          select analytictype,
                 analyticname,
                 relationtype1 as "RelationCode1"
            from analytictypes
           where altermode = -1
             and visibleforusers = 1
           order by analyticname;

    end case;

    return Result;
  exception
    when others then
      pkg_exceptions.AddException(sqlcode,
                                  sqlerrm,
                                  'pkg_analytic.GetAnalyticTypesInfo');
      Result := -1; --Общая ошибка
      return Result;
  end;

  function GetFullAnalyticInfo(pMode_in char, pResCursor out sys_refcursor)
    return number is
    Result number default 0;
  begin
    case pMode_in
      when 'r' then
        open pResCursor for
          select t.analyticname,
                 t.analytictype,
                 c.analytictype,
                 c.analyticcode,
                 c.analyticname
            from analytictypes t
           right join analyticcodes c
              on t.analytictype = c.analytictype
           where c.altermode != -1
           order by t.analytictype;
      when 'l' then
        open pResCursor for
          select t.analyticname,
                 t.analytictype,
                 c.analytictype,
                 c.analyticcode,
                 c.analyticname
            from analytictypes t
            left join analyticcodes c
              on t.analytictype = c.analytictype
           where c.altermode != -1
              or c.altermode is null
           order by t.analytictype;
      when 'i' then
        open pResCursor for
          select t.analyticname,
                 t.analytictype,
                 c.analytictype,
                 c.analyticcode,
                 c.analyticname
            from analytictypes t
           inner join analyticcodes c
              on t.analytictype = c.analytictype
           where c.altermode != -1
           order by t.analytictype;
      when 'f' then
        open pResCursor for
          select t.analyticname,
                 t.analytictype,
                 c.analytictype,
                 c.analyticcode,
                 c.analyticname
            from analytictypes t
            full join analyticcodes c
              on t.analytictype = c.analytictype
           where c.altermode != -1
              or c.altermode is null
           order by t.analytictype;
      else
        Result := -411; --неправильно введен параметр режима объединения таблиц
    end case;
    return Result;
  exception
    when others then
      pkg_exceptions.AddException(sqlcode,
                                  sqlerrm,
                                  'pkg_analytic.GetFullAnalyticInfo');
      Result := -1; --Общая ошибка
      return Result;
  end GetFullAnalyticInfo;

  function GetFullAnalyticInfoWithHiden(pMode_in   char,
                                        pResCursor out sys_refcursor)
    return number is
    Result number default 0;
  begin
    case pMode_in
      when 'r' then
        open pResCursor for
          select t.analyticname,
                 t.analytictype,
                 c.analytictype,
                 c.analyticcode,
                 c.analyticname
            from analytictypes t
           right join analyticcodes c
              on t.analytictype = c.analytictype
           order by t.analytictype;
      when 'l' then
        open pResCursor for
          select t.analyticname,
                 t.analytictype,
                 c.analytictype,
                 c.analyticcode,
                 c.analyticname
            from analytictypes t
            left join analyticcodes c
              on t.analytictype = c.analytictype
           order by t.analytictype;
      when 'i' then
        open pResCursor for
          select t.analyticname,
                 t.analytictype,
                 c.analytictype,
                 c.analyticcode,
                 c.analyticname
            from analytictypes t
           inner join analyticcodes c
              on t.analytictype = c.analytictype
           order by t.analytictype;
      when 'f' then
        open pResCursor for
          select t.analyticname,
                 t.analytictype,
                 c.analytictype,
                 c.analyticcode,
                 c.analyticname
            from analytictypes t
            full join analyticcodes c
              on t.analytictype = c.analytictype
           order by t.analytictype;
      else
        Result := -411; --неправильно введен параметр режима объединения таблиц
    end case;
    return Result;
  exception
    when others then
      pkg_exceptions.AddException(sqlcode,
                                  sqlerrm,
                                  'pkg_analytic.GetFullAnalyticInfoWithHiden');
      Result := -1; --Общая ошибка
      return Result;
  end GetFullAnalyticInfoWithHiden;

  --AddAnalyticCode
  function AddAnalyticCode(pAnalyticType_in  in number,
                           pAnalyticCode_in  in number,
                           pAnalyticName_in  in varchar2,
                           pShortName_in     in varchar2,
                           pRelationType1_in in number) return number is
    Result             number default 0;
    vCountAnalyticType number;
    cAlterMode constant number := 0;
  begin
    select count(*)
      into vCountAnalyticType
      from analytictypes t
     where t.analytictype = pAnalyticType_in;
    if vCountAnalyticType = 1 then
      begin
        select count(*)
          into Result
          from analyticcodes c
         where c.analyticcode = pAnalyticCode_in
           and c.analytictype = pAnalyticType_in;
        if Result = 0 then
          begin
            insert into analyticcodes
              (analytictype,
               analyticcode,
               analyticname,
               shortname,
               relationcode1,
               alterdate,
               altermode)
            values
              (pAnalyticType_in,
               pAnalyticCode_in,
               pAnalyticName_in,
               pShortName_in,
               pRelationType1_in,
               sysdate,
               cAlterMode);
          end;
        else
          Result := -408; --повторная запись для заданного кода аналитической информации
        end if;
      end;
    elsif vCountAnalyticType = 0 then
      begin
        Result := -409; --нет такого типа аналитической информации
      end;
    else
      Result := -412; --обнаружены одинаковые типы аналитической информации
    end if;
    return Result;
  exception
    when others then
      pkg_exceptions.AddException(sqlcode,
                                  sqlerrm,
                                  'pkg_analytic.AddAnalyticCode');
      Result := -1; --Общая ошибка
      return Result;
  end AddAnalyticCode;

  --AddAnalyticType
  function AddAnalyticType(pAnalyticType_in  in number,
                           pAnalyticName_in  in varchar2,
                           pRelationType1_in in number) return number is
    Result number default 0;
    cAlterMode constant number := 0;
  begin
    select count(*)
      into Result
      from analytictypes t
     where t.analytictype = pAnalyticType_in;
    if Result = 0 then
      begin
        insert into analytictypes
          (analytictype,
           analyticname,
           relationtype1,
           alterdate,
           altermode,
           visibleforusers)
        values
          (pAnalyticType_in,
           pAnalyticName_in,
           pRelationType1_in,
           sysdate,
           cAlterMode,
           1);
        Result := 0;
      end;
    else
      Result := -408; --повторная запись для заданного типа аналитической информации
    end if;
    return Result;
  exception
    when others then
      pkg_exceptions.AddException(sqlcode,
                                  sqlerrm,
                                  'pkg_analytic.AddAnalyticType');
      Result := -1; --Общая ошибка
      return Result;
  end AddAnalyticType;

  --ChangeAnalyticCode
  function ChangeAnalyticCode(pAnalyticType_in  in number,
                              pAnalyticCode_in  in number,
                              pAnalyticName_in  in varchar2,
                              pShortName_in     in varchar2,
                              pRelationType1_in in number) return number is
    Result             number default 0;
    vCountAnalyticType number;
    vCountAnalyticCode number;
    --cAlterMode constant number := 1;
  begin
    select count(*)
      into vCountAnalyticType
      from analytictypes t
     where t.analytictype = pAnalyticType_in;
    if vCountAnalyticType = 1 then
      begin
        select count(*)
          into vCountAnalyticCode
          from analyticcodes c
         where c.analyticcode = pAnalyticCode_in
           and c.analytictype = pAnalyticType_in;
        if vCountAnalyticCode = 1 then
          begin
            update analyticcodes
               set analyticname  = pAnalyticName_in,
                   shortname     = pShortName_in,
                   relationcode1 = pRelationType1_in,
                   alterdate     = sysdate
             where analyticcode = pAnalyticCode_in
               and analytictype = pAnalyticType_in;
            update analytictypes
               set alterdate = sysdate
             where analytictype = pAnalyticType_in;
            Result := 0;
          end;
        elsif vCountAnalyticCode = 0 then
          Result := -410; --нет такого кода аналитической информации
        else
          Result := -413; --обнаружены одинаковые коды аналитической информации
        end if;
      end;
    elsif vCountAnalyticType = 0 then
      Result := -409; --нет такого типа аналитической информации
    else
      Result := -412; --обнаружены одинаковые типы аналитической информации
    end if;
    return Result;
  exception
    when others then
      pkg_exceptions.AddException(sqlcode,
                                  sqlerrm,
                                  'pkg_analytic.ChangeAnalyticCode');
      Result := -1; --Общая ошибка
      return Result;
  end ChangeAnalyticCode;

  --ChangeAnalyticType
  function ChangeAnalyticType(pAnalyticType_in  in number,
                              pAnalyticName_in  in varchar2,
                              pRelationType1_in in number) return number is
    Result             number default 0;
    vCountAnalyticType number;
    --cAlterMode constant number := 1;
  begin
    select count(*)
      into vCountAnalyticType
      from analytictypes t
     where t.analytictype = pAnalyticType_in;
    if vCountAnalyticType = 1 then
      begin
        update analytictypes
           set analyticname  = pAnalyticName_in,
               relationtype1 = pRelationType1_in,
               alterdate     = sysdate
         where analytictype = pAnalyticType_in;
        Result := 0;
      end;
    elsif vCountAnalyticType = 0 then
      Result := -409; --нет такого типа аналитической информации
    else
      Result := -412; --обнаружены одинаковые типы аналитической информации
    end if;
    return Result;
  exception
    when others then
      pkg_exceptions.AddException(sqlcode,
                                  sqlerrm,
                                  'pkg_analytic.ChangeAnalyticType');
      Result := -1; --Общая ошибка
      return Result;
  end ChangeAnalyticType;

  --containsCode
  function containsCode(pAnalyticType_in in number,
                        pAnalyticCode_in in number) return boolean is
    Result             boolean default false;
    vCountAnalyticType number;
    vCountAnalyticCode number;
  begin
    select count(*)
      into vCountAnalyticType
      from analytictypes t
     where t.analytictype = pAnalyticType_in;
    if vCountAnalyticType = 1 then
      begin
        select count(*)
          into vCountAnalyticCode
          from analyticcodes c
         where c.analyticcode = pAnalyticCode_in
           and c.analytictype = pAnalyticType_in;
        if vCountAnalyticCode = 1 then
          Result := true;
        else
          Result := false;
        end if;
      end;
    else
      Result := false;
    end if;
    return Result;
  exception
    when others then
      pkg_exceptions.AddException(sqlcode,
                                  sqlerrm,
                                  'pkg_analytic.containsCode');
      return null;
  end containsCode;

  function containsCode1(pAnalyticType_in in number,
                         pAnalyticCode_in in varchar2) return number is
    Result             number default 0;
    vCountAnalyticType number;
    vCountAnalyticCode number;
  begin
    if pAnalyticCode_in is null then
      return 1;
    end if;
    begin
      vCountAnalyticCode := to_number(pAnalyticCode_in);
    exception
      when others then
        return 0;
    end;

    select count(*)
      into vCountAnalyticType
      from analytictypes t
     where t.analytictype = pAnalyticType_in;
    if vCountAnalyticType = 1 then
      begin
        select count(*)
          into vCountAnalyticCode
          from analyticcodes c
         where c.analyticcode = pAnalyticCode_in
           and c.analytictype = pAnalyticType_in;
        if vCountAnalyticCode = 1 then
          Result := 1;
        else
          Result := 0;
        end if;
      end;
    else
      Result := 0;
    end if;
    return Result;
  exception
    when others then
      pkg_exceptions.AddException(sqlcode,
                                  sqlerrm,
                                  'pkg_analytic.containsCode');
      return null;
  end containsCode1;

  --containsType
  function containsType(pAnalyticType_in in number) return boolean is
    Result             boolean default false;
    vCountAnalyticType number;
  begin
    select count(*)
      into vCountAnalyticType
      from analytictypes t
     where t.analytictype = pAnalyticType_in;
    if vCountAnalyticType = 1 then
      Result := true;
    else
      Result := false;
    end if;
    return Result;
  exception
    when others then
      pkg_exceptions.AddException(sqlcode,
                                  sqlerrm,
                                  'pkg_analytic.containsType');
      return null;
  end containsType;

  --DeleteAnalyticCode
  function DeleteAnalyticCode(pAnalyticType_in in number,
                              pAnalyticCode_in in number) return number is
    Result number default 0;
    cAlterMode constant number := -1;
  begin
    update analyticcodes
       set alterdate = sysdate, altermode = cAlterMode
     where analytictype = pAnalyticType_in
       and analyticcode = pAnalyticCode_in;
    return Result;
  exception
    when others then
      pkg_exceptions.AddException(sqlcode,
                                  sqlerrm,
                                  'pkg_analytic.HideAnalyticCode');
      Result := -1; --Общая ошибка
      return Result;
  end DeleteAnalyticCode;

  --DeleteAnalyticType
  function DeleteAnalyticType(pAnalyticType_in in number) return number is
    Result number default 0;
    cAlterMode constant number := -1;
  begin

    update analyticcodes
       set alterdate = sysdate, altermode = cAlterMode
     where analytictype = pAnalyticType_in;
    update analytictypes
       set alterdate = sysdate, altermode = cAlterMode
     where analytictype = pAnalyticType_in;

    return Result;
  exception
    when others then
      pkg_exceptions.AddException(sqlcode,
                                  sqlerrm,
                                  'pkg_analytic.HideAnalyticType');
      Result := -1; --Общая ошибка
      return Result;
  end DeleteAnalyticType;

  --OpenAnalyticType
  function OpenAnalyticType(pAnalyticType in number) return number is
  begin
    update Analytictypes
       set altermode = 0, alterdate = sysdate
     where analytictype = pAnalyticType
       and altermode = -1;
    return 0;
  end;

  --OpenAnalyticCode
  function OpenAnalyticCode(pAnalyticType in number,
                            pAnalyticCode in number) return number is
    vcount number default 0;
  begin
    select count(*)
      into vcount
      from Analytictypes
     where altermode <> -1
       and analytictype = pAnalyticType;
    if vcount = 1 then
      update Analyticcodes
         set altermode = 0, alterdate = sysdate
       where analytictype = pAnalyticType
         and analyticcode = pAnalyticCode
         and altermode = -1;
    else
      return - 414; -- Невозможно восстановить код, так как закрыт справочник
    end if;
    return 0;
  end;

  --GetDescription
  function GetDescription(pCode in number, pType in number) return varchar2 is
    result varchar2(1000 CHAR) default null;
  begin
    if pCode is null then
      result := '';
    else
      select analyticname
        into result
        from analyticcodes
       where analytictype = pType
         and analyticcode = pCode;
    end if;
    return result;
  exception
    when others then
      return pCode || '--Значение не найдено в справочнике';
  end;

  --GetShortDescription
  function GetShortDescription(pCode in number,
                               pType in number) return varchar2 is
    result varchar2(1000 CHAR) default null;
  begin
 Case pType
    when 41021 then -- OKEDCODE 2 OKED2AC
    	SELECT AC.SHORTNAME
          INTO result
          FROM ANALYTICCODES ac
         WHERE AC.ANALYTICTYPE = 41021 AND AC.OUTER_CODE = pCode;
    when 41019 then -- OKSMT 2 OKED2AC
	 	 SELECT AC.SHORTNAME
          INTO result
          FROM ANALYTICCODES ac
         WHERE AC.ANALYTICTYPE = 41019 AND AC.OUTER_CODE = pCode;
     else
      select a.shortname
      into result
      from analyticcodes a
      where analytictype = pType
      and analyticcode = pCode;
    end case;
    return result;
  exception
    when others then
      return pCode || '--Значение не найдено в справочнике';
  end GetShortDescription;

  function GetMessName(messtypeid number) return nvarchar2 is
    mess  nvarchar2(300);
    vlang varchar2(30 CHAR);
  begin
    vlang := pkg_main.GetUserLangSettings;
    case vlang
      when 'Kazakh' then
        select mess_name_kz
          into mess
          from messages_types
         where mess_type = messtypeid;
      else
        select mess_name
          into mess
          from messages_types
         where mess_type = messtypeid;
    end case;
    return mess;
  exception
    when others then
      begin
        case vlang
          when 'Kazakh' then
            select mess_name_kz
              into mess
              from messages_types
             where mess_type = -1;
          else
            select mess_name
              into mess
              from messages_types
             where mess_type = -1;
        end case;
        return mess;
      exception
        when others then
          return 'Неизвестный тип';
      end;
  end;

  function GetCodeDescription(pCodeVal  number,
                              pDataCode number,
                              pVersion  number) return varchar2 is
    pType number;
  begin
    begin

      select analytictype
        into pType
        from analytictypes_vers_depend
       where datacode = pDataCode
         and version = pVersion;

    exception
      when no_data_found then
        return pCodeVal || ' - Значение не найдено в справочнике'; --Ошибка в прааметрах настройки и прописанных справочниках
    end;
    return GetDescription(pCodeVal, pType);
  end;

  function GetShortCodeDescription(pCodeVal  number,
                                   pDataCode number,
                                   pVersion  number) return varchar2 is
    pType number;
  begin
    begin

      select analytictype
        into pType
        from analytictypes_vers_depend
       where datacode = pDataCode
         and version = pVersion;

    exception
      when no_data_found then
        return pCodeVal || ' - Значение не найдено в справочнике'; --Ошибка в прааметрах настройки и прописанных справочниках
    end;
    return GetShortDescription(pCodeVal, pType);
  end;

  function GetRelationCodesInfo(pRelationAnalyticType in number,
                                pRelationAnalyticCode in number,
                                pCodesListType        in number,
                                pResCursor            out sys_refcursor,
                                pLanguageCode         in number default 1)
    return number is
    Result number default 0;
    --  isenabled   boolean default true;
  begin
    case pCodesListType
      when 1 then
        open pResCursor for
          select analyticcode,
                 shortname,
                 analyticname,
                 relationcode1,
                 1 as isenabled
            from analyticcodes
           where analytictype = pRelationAnalyticType
             and relationcode1 = pRelationAnalyticCode
             and altermode != -1
           order by analyticcode;
      when 2 then
        open pResCursor for
          select analyticcode,
                 shortname,
                 analyticname,
                 relationcode1,
                 decode(altermode, -1, 0, 1) as isenabled
            from analyticcodes
           where analytictype = pRelationAnalyticType
             and relationcode1 = pRelationAnalyticCode
           order by analyticcode;
      when 0 then
        open pResCursor for
          select analyticcode,
                 shortname,
                 analyticname,
                 relationcode1,
                 0 as isenabled
            from analyticcodes
           where analytictype = pRelationAnalyticType
             and relationcode1 = pRelationAnalyticCode
             and altermode = -1
           order by analyticcode;

    end case;
    return Result;
  exception
    when others then
      pkg_exceptions.AddException(sqlcode,
                                  sqlerrm,
                                  'pkg_analytic.GetAnalyticCodesInfo');
      Result := -1; --Общая ошибка
      return Result;
  end;

  function GetListOfSwiftCodes(pBankSwiftCode      in varchar2,
                               pBankSwiftCodesList out sys_refcursor)
    return number is
    result number default 0;
  begin
    open pBankSwiftCodesList for
      select bic as BankSwiftCode --name
        from swift_codes
       where bic like pBankSwiftCode || '%'
          or pBankSwiftCode is null
       order by bic;
    return result;
  end;

  function GetSwiftCodeParams(pBankSwiftCode    in varchar2,
                              pBankSwiftName    out varchar2,
                              pBankSwiftCountry out number,
                              pCity             out varchar2) return number is
    result number default 0;
  begin

    select name,
           case country
             when 'KAZAKHSTAN' then
              398
             else
              null
           end,
           city
      into pBankSwiftName, pBankSwiftCountry, pCity
      from swift_codes
     where bic = pBankSwiftCode;
    return result;
  exception
    when others then
      return Result;
  end;

 -- Проверка varchar - если число - возвращает число, иначе null
FUNCTION to_Number_Or_Null (p_Value VARCHAR2) RETURN NUMBER IS
  v_res Number;
BEGIN
  RETURN to_Number (p_Value);
EXCEPTION
  WHEN others THEN
    RETURN NULL;
END to_Number_Or_Null;

    --GetCountryDescription - наименование страны, или из кодов аналитики (Web) или из перевязочной таблицы (АРМ)
  function GetCountryDescription(pCode in varchar2) return varchar2 is
    result varchar2(1000 CHAR) default null;
   -- v_pCode Number;
  begin
      SELECT AC.ANALYTICNAME
          INTO result
          FROM ANALYTICCODES ac
         WHERE AC.ANALYTICTYPE = 41019 AND AC.OUTER_CODE = pCode;
      
    return result;
  exception
    when others then
      return pCode || '--Значение не найдено в справочнике';
  end GetCountryDescription;

end PKG_Analytic;
/

CREATE OR REPLACE PUBLIC SYNONYM PKG_ANALYTIC FOR KFM.PKG_ANALYTIC;
GRANT EXECUTE ON KFM.PKG_ANALYTIC TO KFM_ROLE;
