Написано: 07.10.2018

Доработка системы INTEXP для взаимодействия с модулем VBR+

Выполнил большую доработку системы INTEXP для осуществления взаимодествия с модулем VBR+.

Задача ставилась следующим образом:

В билинговой системе ICS могут быть реализованы не все сценарии расчета, необходимые бизнесу. С одной стороны, существуют более сложные схемы вольюмных расчетов чем те, которые можно реализовать средствами ICS. С другой стороны, условия расчета могут быть сформулированы таким образом, что производить расчет нужно на основании данных, расчтываемых в разных инстансах ICS (что принципиально нереализуемо в данных из одного инстанса).

Поэтому было принято решение разработать отдельный модуль (VBR+), который бы занимался необходимыми расчетами.

Одновременно в системе INTEXP небходимо было выполнить доработки для обеспечения взаимодействия с этим модулем.

Ниже приведена схема, иллюстрирующая взаимодействие между системами.

Архитектура взаимодействия

Главным образом, система INTEXP должна:

1) Предоставить данные модулю VBR+.   
2) Получить результаты расчета от модуля VBR+ и консолидировать их с исходными данными.  

В остальном система INTEXP должна функционировать прежним образом (то есть предоставлять данные в системы Софтел, PartnerReports и Crm3)

Ниже приведен пример диаграммы использования системы INTEXP во время билинг-цикла.

Диаграмма использования

Требования к доработке.

1.	Функциональные требования.  
    ФТ1.	Реализовать в IntExp объекты для предоставления информации модулю VBRP.
    ФТ2.	Реализовать в IntExp функции для модуля VBRP для предоставления информации.
    ФТ3.	Реализовать в IntExp функции получения информации от модуля VBRP о результатах расчета.
    ФТ4.	Реализовать в IntExp механизм объединения результатов расчета из ICS с результатами расчета из модуля VBRP, а также передачи этих данных при экспорте в системы Софтел, crm3 и PartnerReports.
    ФТ5.	Реализовать в IntExp в модуле IE2 (выгрузка из ICS offline) интерфейсы получения данных от модуля VBRPlus, а также отображения данных расчета VBRPlus и консолидированных данных.
    ФТ6.	Реализовать в IntExp в модуле ictrep7 (модуль отчетов) функционал предоставления отчетов VbrPlusSummary (для отображения информации из систем ICS и VBRP)
    ФТ7.	Реализовать в IntExp в модуле IE3 (выгрузка из ICS online) интерфейсы получения данных от модуля VBRPlus, а также отображения данных расчета VBRPlus и консолидированных данных.

2.	НеФункциональные требования.
    НФТ1.	В INTEXP нужно обеспечить хранение результатов расчета модуля VBRP в течении 3-лет.

Ниже приведена диаграмма компонентов:

Диаграмма компонентов

Далее приведен фрагмент из Технического Задания со списком интерфейсных объектов, которые INTEXP использует в модуле VBR+.

Список объектов модуля VBR+ для INTEXP

В соответствии с Техническим Заданием и Функциональным Диазайном (здесь не приведены) был реализован механизм междусистемного взаимодействия с модулем VBR+.

Ниже приведен один из пакетов, реализующий данную функциональность.

Описание пакета VBR

CREATE OR REPLACE 
PACKAGE vbr
  IS
  ---------------------------------------------------------------
  --    Функциональность для VBR+
  ---------------------------------------------------------------
    gPM varchar2(10) := 'VBRP';       -- Метка пакета (в логах и журналах)

    -- Сформировать задание на предоставление данных из ICS offline для VBR+
    -- 
    PROCEDURE GetGt7 (                       
        p_From IN date                           -- Дата начала периода предоставления данных
        , p_To IN date DEFAULT null             -- Дата окончания периода предоставления данных. Если NULL, то используется последний день месяца для параметра p_From
        , p_Scala IN varchar2 DEFAULT null        -- скала, по которой сформировать данные
        , p_InvDir IN varchar2 DEFAULT null        -- направление счета
        , p_SnapID OUT number                    -- временная метка формирования данных
    );

    -- Сформировать задание на предоставление данных из ICS online для VBR+
    -- Результат -- в v_dailysum_vk
    -- 
    PROCEDURE GetVk (                       
        p_From IN date                          -- Дата начала периода предоставления данных
        , p_To IN date DEFAULT null             -- Дата окончания периода предоставления данных. Если NULL, то используется последний день месяца для параметра p_From
        , p_Scala IN varchar2 DEFAULT null        -- скала, по которой сформировать данные
        , p_InvDir IN varchar2 DEFAULT null        -- направление счета
        , p_SnapID OUT number                    -- возвращается номер среза
    );

    -- Сформировать задание на удаление данных из представления.
    -- 
    PROCEDURE ClearData (       
        p_ViewName IN varchar2                   -- Имя представления, данные которого обработаны и могут быть удалены
        , p_SnapID IN number                    -- Номер среза данных.
    );
                
    -- Сформировать задание на получение данных от VBR+.
    -- 
    PROCEDURE DoneVbrProcess (       
        p_BatchID IN number                        -- Номер пачки результата расчета модуля VBR+
    );
                
    -- Выполнить задание из очереди
    -- 
    PROCEDURE Run;

    -- Сформировать задание на отправку данных в VBR+.
    -- 
    PROCEDURE SendVbrData (       
        p_Src IN char                            -- Инстанс
        , p_Year IN number                        -- год
        , p_Month IN number                        -- месяц
    );
                
    -- Сформировать задание на отправку справочников в VBR+.
    -- 
    PROCEDURE SendRef (       
        p_Src IN char DEFAULT '0'                  -- Инстанс
        , p_Mask IN varchar2 DEFAULT 'A'        -- маска
        , p_From IN date DEFAULT null             -- дата начала периода
        , p_To IN date DEFAULT null                -- дата завершения периода
    );
                
END;
/

Фрагмент процедуры VBR.Run()

Ниже приведен фрагмент процедуры VBR.Run(), которая осуществляет выполенение задания из очереди.

Задания представляют собой записи в таблице task_list.

Таблица партиционирована по полю status, которое семантически представляет собой статус задания.

Если в очереди есть задание со статусом p_ready (готовое к выполнению), данное задание переводится в состояние p_processed (выполняется), после чего в зависимости от типа задания (поля task_type) осуществляется выполнение задания.

После того, как задание будет обработано, оно переводится в состояние p_done (если обработка произведена успешно), либо в состояние p_error (ошибка).

CREATE OR REPLACE 
PACKAGE BODY vbr
IS
    --------------------------------------------------------------
    --    Функциональность для VBR+
    --------------------------------------------------------------

    ...
    
---------------------------------------------------------------------------
-- Выполнить задание из очереди
---------------------------------------------------------------------------
PROCEDURE Run
IS
    x_TaskID number;
    x_TaskType varchar2(20);
    x_TaskStatus number;
    x_Err number;
    x_Ok boolean;
    x_Rows number;
    pragma autonomous_transaction;
BEGIN
    -- Начинаем выполнять задание
    update task_list partition (p_ready) r 
    set r.task_status = 1, start_date = sysdate, end_date = null
    where r.task_id = (select min(task_id) from task_list partition (p_ready))
    and r.task_type in ('DoneVbrProcess', 'GetGt7', 'GetVk'
        , 'ClearData', 'SendVbrData', 'SendRef')
    returning r.task_id, r.task_type, r.errors
    into x_TaskID, x_TaskType, x_Err;
    x_Rows := SQL%ROWCOUNT;

    commit;

    -- Выходим, если в очереди нет заданий.
    if ( x_Rows = 0 ) then
        return ;
    end if;

    -- Выполняем задачу
    if(x_TaskType = 'DoneVbrProcess') then
        x_Ok := DoDoneVbrProcess(x_TaskID);
    elsif(x_TaskType = 'GetGt7') then
        x_Ok := DoGetGt7(x_TaskID);
    elsif(x_TaskType = 'GetVk') then
        x_Ok := DoGetVk(x_TaskID);
    elsif(x_TaskType = 'ClearData') then
        x_Ok := DoClearData(x_TaskID);
    elsif(x_TaskType = 'SendVbrData') then
        x_Ok := DoSendVbrData(x_TaskID);
    elsif(x_TaskType = 'SendRef') then
        x_Ok := DoSendRef(x_TaskID);
    end if;

    if(x_Ok = true) then
        x_TaskStatus := 2;
    else 
        x_TaskStatus := 9;
        x_Err := x_Err + 1;
    end if;

    -- завершаем выполнение
    update task_list r
    set r.task_status = x_TaskStatus, r.end_date = sysdate, r.errors = x_Err
    where r.task_id = x_TaskID;
    commit;

EXCEPTION WHEN OTHERS THEN
    rollback;
    P_LOG_MSG(gPM, 'Ошибка в процедуре VBR.Run()');
END;


-- Конец пакета
END;
/