Advertisement
Guest User

Untitled

a guest
Aug 21st, 2017
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
SQL 58.54 KB | None | 0 0
  1. CREATE OR REPLACE package body sc_cp_bis_ord_rateplan_pack_pg
  2.   --
  3.   ---@ SCC_CP
  4.   ----- Тело пакета серверной части Corporate Portal
  5.   ------ 020.08
  6.   --
  7.   -- SC_CP_BIS
  8.   --
  9.   -- Copyright (c) CJSC PETER-SERVICE, 2017.
  10.   --
  11.   -- Мочалов Дмитрий Эдуардович
  12.   --
  13.   -- Серверная логика взаимодействия с PETER-SERVICE BIS (Обработка заказа: Тарифный план и пакет опций)
  14.   --
  15.   -- Версия Дата       Автор               Изменение
  16.   -- ------ ---------- ------------------- -------------------------------------------------------------------------------
  17.   -- 020.08 21.08.2017 Мочалов Д.Э.        [SUBS-212089] Добавлена процедура connect_pack_to_rtpl
  18.   -- 020.06 16.03.2017 Lev.Khruschev       BTS-152550 фикс формирования статусов заказа
  19.   --
  20.   -- 020.05 28.02.2017 Мочалов Д.Э.        Создание пакета
  21.   --
  22. IS
  23.  
  24.   CURRENT_VERSION_PB constant varchar2(32) := '020.08';
  25.  
  26.  
  27.   ------------------------------------------------------------------------------------------------------------------------
  28.   -- КОНСТАНТЫ И ТИПЫ ДАННЫХ
  29.   ------------------------------------------------------------------------------------------------------------------------
  30.  
  31.   --
  32.   -- Параметры обработчиков
  33.   --
  34.   subtype t_cphp_id IS cp_ord_hndl_params.cphp_id%TYPE;
  35.   --
  36.   -- Изменение ТП: подтверждение
  37.   GC_PRMT_C_CLNT_IDS       constant t_cphp_id := GC_FULL_APPL_ID + 241; -- Список идентификаторов клиентов
  38.   GC_PRMT_C_SUBS_IDS       constant t_cphp_id := GC_FULL_APPL_ID + 242; -- Список идентификаторов абонентов
  39.   GC_PRMT_C_RTPL_ID        constant t_cphp_id := GC_FULL_APPL_ID + 243; -- Идентификатор ТП
  40.   GC_PRMT_C_PACK_IDS       constant t_cphp_id := GC_FULL_APPL_ID + 244; -- Идентификаторы пакетов
  41.   GC_PRMT_C_PACK_TYPE      constant t_cphp_id := GC_FULL_APPL_ID + 245; -- Тип пакета (периодический или разовый)
  42.   GC_PRMT_C_DATE_FROM      constant t_cphp_id := GC_FULL_APPL_ID + 246; -- Дата смены ТП
  43.   GC_PRMT_C_DATE_FROM_LIST constant t_cphp_id := GC_FULL_APPL_ID + 247; -- Список дат смены ТП по абонентам
  44.   --
  45.   -- Изменение ТП: выполнение
  46.   GC_PRMT_A_CLNT_IDS       constant t_cphp_id := GC_FULL_APPL_ID + 248; -- Список идентификаторов клиентов
  47.   GC_PRMT_A_SUBS_IDS       constant t_cphp_id := GC_FULL_APPL_ID + 249; -- Список идентификаторов абонентов
  48.   GC_PRMT_A_RTPL_ID        constant t_cphp_id := GC_FULL_APPL_ID + 250; -- Идентификатор ТП
  49.   GC_PRMT_A_PACK_IDS       constant t_cphp_id := GC_FULL_APPL_ID + 251; -- Идентификаторы пакетов
  50.   GC_PRMT_A_PACK_TYPE      constant t_cphp_id := GC_FULL_APPL_ID + 252; -- Тип пакета (периодический или разовый)
  51.   GC_PRMT_A_DATE_FROM      constant t_cphp_id := GC_FULL_APPL_ID + 253; -- Дата смены ТП
  52.   GC_PRMT_A_DATE_FROM_LIST constant t_cphp_id := GC_FULL_APPL_ID + 254; -- Список дат смены ТП по абонентам
  53.  
  54.  
  55.   -- Возвращает версию тела пакета.
  56.   FUNCTION get_package_version
  57.     RETURN varchar2 deterministic
  58.   IS
  59.     BEGIN
  60.       RETURN CURRENT_VERSION_PB;
  61.     END get_package_version;
  62.  
  63.   -- Регистрирует заказ на изменение ПАКЕТНОГО ТП вместе с опциями (с возможностью немедленного выполнения заказа на подтверждение в новом режиме).
  64.   FUNCTION reg_rate_plan_pack_change(
  65.     p_cpoh_id              IN cp_order_handler.cpoh_id%TYPE,
  66.     p_cpcl_id              IN cp_clients.cpcl_id%TYPE,
  67.     p_navi_user            IN varchar2,
  68.     p_cpor_id              IN cp_orders.cpor_id%TYPE              := NULL,
  69.     p_clnt_list            IN sc_cp_common_pg.array_number        := sc_cp_common_pg.empty_array_number,
  70.     p_subs_list            IN sc_cp_common_pg.array_number,
  71.     p_rtpl_id              IN rate_plans.rtpl_id%TYPE             := NULL,
  72.     p_pack_list            IN sc_cp_common_pg.array_number        := sc_cp_common_pg.empty_array_number,
  73.     p_in_date_from         IN varchar2                            := NULL,
  74.     p_cp_zone_id           IN zones.zone_id%TYPE,
  75.     p_processing_mode      IN cp_orders.processing_mode%TYPE      := NULL,
  76.     p_notify_subs_by_sms   IN cp_orders.notify_subs_by_sms%TYPE   := NULL,
  77.     p_notify_user_by_sms   IN cp_orders.notify_user_by_sms%TYPE   := NULL,
  78.     p_notify_user_by_email IN cp_orders.notify_user_by_email%TYPE := NULL,
  79.     p_susr_id              IN sc_users.susr_id%TYPE               := NULL
  80.   )
  81.     RETURN cp_orders.cpor_id%TYPE
  82.   IS
  83.     -- признак нового режима обработки заказ а
  84.     C_IS_NEW_MODE       constant BOOLEAN := p_processing_mode IS NOT NULL;
  85.  
  86.     -- общие
  87.     v_clnt_list         sc_cp_common_pg.array_number;
  88.     v_subs_list         sc_cp_common_pg.array_number;
  89.     v_subs_rownums      cp_tb_number;
  90.  
  91.     -- дополнительные
  92.     v_rtpl_id           rate_plans.rtpl_id%TYPE;
  93.     v_pack_list         sc_cp_common_pg.array_number;
  94.     v_pack_type         NUMBER;
  95.     v_in_date_from      DATE;
  96.     v_in_date_from_list sc_cp_common_pg.array_date;
  97.  
  98.     -- количество всех абонентов в заказе на "подтверждение"
  99.     v_subs_all_count    pls_integer;
  100.  
  101.     -- идентификатор созданного заказа
  102.     v_cpor_id           cp_orders.cpor_id%TYPE;
  103.     BEGIN
  104.       -- ===================================================================================================================
  105.       -- проверяем/подготавливаем необходимые параметры
  106.       -- ===================================================================================================================
  107.      
  108.       -- инициализируем переменные значениями параметров
  109.       v_clnt_list := p_clnt_list;
  110.       v_subs_list := p_subs_list;
  111.       v_rtpl_id   := p_rtpl_id;
  112.       -- опции
  113.       v_pack_list := p_pack_list;
  114.      
  115.       -- проверяем/получаем параметры
  116.       IF
  117.       p_cpoh_id = GC_HANDL_CONFIRM
  118.       OR ( -- "выполнение" в новом режиме без предварительного "подтверждения"
  119.         p_cpoh_id = GC_HANDL_ACTION
  120.         AND p_cpor_id IS NULL
  121.       )
  122.       THEN
  123.         -------------------------------
  124.         -- используем входные параметры
  125.         -------------------------------
  126.  
  127.         -- проверяем входные данные
  128.         IF v_subs_list.COUNT = 0 THEN
  129.           -- не заданы абоненты (error_code: 150080004)
  130.           sc_cp_common_pg.raise_custom_error(
  131.               error => sc_cp_common_pg.err_param_subs_list_empty
  132.           );
  133.         elsif v_rtpl_id IS NULL THEN
  134.           -- не задан ТП (error_code: 150190003)
  135.           sc_cp_common_pg.raise_custom_error(
  136.               error => sc_cp_bis_common_pg.err_param_rtpl_empty
  137.           );
  138.         END IF;
  139.  
  140.         -- преобразуем дату согласно правилам: [CP:+P_CP_ZONE_ID], [CP:ACTION_SYSDATE], [CP:ACTION_FUTURE/PAST]
  141.         sc_cp_bis_common_pg.mutation_date(
  142.             p_date             => sc_cp_common_pg.to_truncated_date(p_in_date_from, 'dd'),
  143.             p_zone_id          => p_cp_zone_id,
  144.             p_subs_list        => v_subs_list,
  145.             p_result_date      => v_in_date_from,
  146.             p_result_date_list => v_in_date_from_list
  147.         );
  148.       elsif p_cpoh_id = GC_HANDL_ACTION THEN
  149.         ------------------------------------------------
  150.         -- получаем параметры от заказа на подтверждение
  151.         ------------------------------------------------
  152.  
  153.         -- проверяем соответствие заказу на подтверждение
  154.         sc_cp_orders_pg.check_action_order(
  155.             p_cpoh_id         => p_cpoh_id,
  156.             p_processing_mode => p_processing_mode,
  157.             p_confirm_cpor_id => p_cpor_id,
  158.             p_confirm_cpoh_id => GC_HANDL_CONFIRM
  159.         );
  160.  
  161.         -- CLNT_ID
  162.         sc_cp_orders_pg.get_param_array(
  163.             p_cpor_id => p_cpor_id,
  164.             p_cphp_id => GC_PRMT_C_CLNT_IDS,
  165.             p_value   => v_clnt_list
  166.         );
  167.  
  168.         -- SUBS_ID
  169.         IF C_IS_NEW_MODE THEN
  170.           -- для нового режима используем входной параметр
  171.           v_subs_list := p_subs_list;
  172.         ELSE
  173.           -- для старого режима (список абонентов, по которым нет ошибок)
  174.           v_subs_list := sc_cp_orders_pg.get_confirmed_subs_list(
  175.               p_cpor_id => p_cpor_id,
  176.               p_cphp_id => GC_PRMT_C_SUBS_IDS
  177.           );
  178.         END IF;
  179.         -- получаем отсортированный упорядоченный список с номерами элементов
  180.         sc_cp_orders_pg.get_sorted_param_array(
  181.             p_cpor_id => p_cpor_id,
  182.             p_cphp_id => GC_PRMT_C_SUBS_IDS,
  183.             p_value   => v_subs_list,
  184.             p_rownums => v_subs_rownums
  185.         );
  186.         IF v_subs_list.COUNT = 0 THEN
  187.           -- не заданы абоненты (error_code: 150080004)
  188.           sc_cp_common_pg.raise_custom_error(
  189.               error => sc_cp_common_pg.err_param_subs_list_empty
  190.           );
  191.         END IF;
  192.  
  193.         -- обязательные параметры
  194.         BEGIN
  195.  
  196.           -- RTPL_ID
  197.           sc_cp_orders_pg.get_param_scalar(
  198.               p_cpor_id => p_cpor_id,
  199.               p_cphp_id => GC_PRMT_C_RTPL_ID,
  200.               p_value   => v_rtpl_id
  201.           );
  202.           IF v_rtpl_id IS NULL THEN
  203.             -- не задан ТП (error_code: 150190003)
  204.             sc_cp_common_pg.raise_custom_error(
  205.                 error => sc_cp_bis_common_pg.err_param_rtpl_empty
  206.             );
  207.           END IF;
  208.  
  209.           -- DATE_FROM (дата в зоне BIS относительно зоны пользователя КП)
  210.           sc_cp_orders_pg.get_param_scalar(
  211.               p_cpor_id => p_cpor_id,
  212.               p_cphp_id => GC_PRMT_C_DATE_FROM,
  213.               p_value   => v_in_date_from
  214.           );
  215.  
  216.           --обязательные параметры для пакетов (тарифных опций)
  217.           IF v_pack_list.COUNT > 0 THEN
  218.             -- PACK_ID
  219.             sc_cp_orders_pg.get_param_array(
  220.                 p_cpor_id   => p_cpor_id,
  221.                 p_cphp_id   => GC_PRMT_C_PACK_IDS,
  222.                 p_value     => v_pack_list,
  223.                 p_mandatory => TRUE
  224.             );
  225.  
  226.             -- PACK_TYPE
  227.             sc_cp_orders_pg.get_param_scalar(
  228.                 p_cpor_id  => p_cpor_id,
  229.                 p_cphp_id  => GC_PRMT_C_PACK_TYPE,
  230.                 p_value    => v_pack_type,
  231.                 p_optional => C_IS_NEW_MODE -- для нового режима параметр необязательный
  232.             );
  233.  
  234.             -- DATE_FROM (даты в зоне BIS относительно зон абонентов)
  235.             sc_cp_orders_pg.get_param_array(
  236.                 p_cpor_id   => p_cpor_id,
  237.                 p_cphp_id   => GC_PRMT_C_DATE_FROM_LIST,
  238.                 p_value     => v_in_date_from_list,
  239.                 p_rownums   => v_subs_rownums, -- поэлементная согласованность со списком абонентов
  240.                 p_mandatory => C_IS_NEW_MODE -- для нового режима параметр обязательный
  241.             );
  242.           END IF;
  243.  
  244.  
  245.         exception
  246.           WHEN NO_DATA_FOUND THEN
  247.           -- параметр не найден (error_code: 150080001)
  248.           sc_cp_common_pg.raise_custom_error(
  249.               error => sc_cp_common_pg.err_param_not_found
  250.           );
  251.         END;
  252.  
  253.         -- меняем статус заказа с типом "подтверждение", на основе которого регистрируется "выполнение"
  254.         --
  255.         -- определяем сколько было всего абонентов в заказе для выставления нужного статуса
  256.         sc_cp_orders_pg.get_count_subs_order(
  257.             p_cpor_id => p_cpor_id,
  258.             p_cphp_id => GC_PRMT_C_SUBS_IDS,
  259.             p_value   => v_subs_all_count
  260.         );
  261.         -- выставлем нужный статус
  262.         sc_cp_orders_pg.change_order_state(
  263.             p_cpor_id    => p_cpor_id,
  264.             p_cpos_id    => CASE WHEN v_subs_list.COUNT = v_subs_all_count
  265.               THEN sc_cp_orders_pg.c_os_confirmed           -- по всем абонентам
  266.                             ELSE sc_cp_orders_pg.c_os_confirmed_partially -- по части абонентов
  267.                             END,
  268.             p_exec_date  => sysdate,
  269.             p_progress   => 1,
  270.             p_autonom_tr => FALSE
  271.         );
  272.       ELSE
  273.         ----------------------------------------------------------
  274.         -- неверный тип обработчика заказа (error_code: 150080007)
  275.         ----------------------------------------------------------
  276.         sc_cp_common_pg.raise_custom_error(
  277.             error => sc_cp_common_pg.err_order_handl_not_found
  278.         );
  279.       END IF;
  280.  
  281.       -- =================================================================================================================
  282.       -- регистрируем заказ
  283.       -- =================================================================================================================
  284.  
  285.       -- проверяем возможность регистрации заказа
  286.       IF
  287.       sc_cp_orders_pg.check_orders(
  288.           p_cpoh_id    => GC_HANDL_CONFIRM,
  289.           p_cpcl_id    => p_cpcl_id,
  290.           p_param_name => sc_cp_orders_pg.c_param_sub_list_name,
  291.           p_subs_list  => v_subs_list
  292.       )
  293.       AND sc_cp_orders_pg.check_orders(
  294.           p_cpoh_id    => GC_HANDL_ACTION,
  295.           p_cpcl_id    => p_cpcl_id,
  296.           p_param_name => sc_cp_orders_pg.c_param_sub_list_name,
  297.           p_subs_list  => v_subs_list
  298.       )
  299.       THEN
  300.         ----------------
  301.         -- создаем заказ
  302.         ----------------
  303.         v_cpor_id := sc_cp_orders_pg.create_orders(
  304.             p_cpoh_id              => p_cpoh_id,
  305.             p_cpcl_id              => p_cpcl_id,
  306.             p_parent_id            => CASE p_cpoh_id WHEN GC_HANDL_ACTION THEN p_cpor_id END,
  307.             p_navi_user            => p_navi_user,
  308.             p_processing_mode      => CASE WHEN p_cpoh_id = GC_HANDL_CONFIRM AND C_IS_NEW_MODE
  309.               THEN sc_cp_orders_pg.GC_PM_PARTIAL
  310.                                       ELSE p_processing_mode
  311.                                       END,
  312.             p_notify_subs_by_sms   => CASE WHEN p_cpoh_id = GC_HANDL_ACTION THEN p_notify_subs_by_sms END,
  313.             p_notify_user_by_sms   => CASE WHEN p_cpoh_id = GC_HANDL_ACTION THEN p_notify_user_by_sms END,
  314.             p_notify_user_by_email => CASE WHEN p_cpoh_id = GC_HANDL_ACTION THEN p_notify_user_by_email END,
  315.             p_susr_id              => p_susr_id
  316.         );
  317.  
  318.         ----------------------
  319.         -- заполняем параметры
  320.         ----------------------
  321.  
  322.         -- CLNT_ID
  323.         sc_cp_orders_pg.create_param_array(
  324.             p_cphp_id => CASE WHEN p_cpoh_id = GC_HANDL_CONFIRM
  325.               THEN GC_PRMT_C_CLNT_IDS
  326.                          ELSE GC_PRMT_A_CLNT_IDS
  327.                          END,
  328.             p_cpor_id => v_cpor_id,
  329.             p_array   => v_clnt_list
  330.         );
  331.  
  332.         -- SUBS_ID
  333.         sc_cp_orders_pg.create_param_array(
  334.             p_cphp_id => CASE WHEN p_cpoh_id = GC_HANDL_CONFIRM
  335.               THEN GC_PRMT_C_SUBS_IDS
  336.                          ELSE GC_PRMT_A_SUBS_IDS
  337.                          END,
  338.             p_cpor_id => v_cpor_id,
  339.             p_array   => v_subs_list
  340.         );
  341.  
  342.         -- RTPL_ID
  343.         sc_cp_orders_pg.create_param_scalar(
  344.             p_cphp_id => CASE WHEN p_cpoh_id = GC_HANDL_CONFIRM
  345.               THEN GC_PRMT_C_RTPL_ID
  346.                          ELSE GC_PRMT_A_RTPL_ID
  347.                          END,
  348.             p_cpor_id => v_cpor_id,
  349.             p_value   => v_rtpl_id
  350.         );
  351.  
  352.         -- PACK_ID
  353.         sc_cp_orders_pg.create_param_array(
  354.             p_cphp_id => CASE WHEN p_cpoh_id = GC_HANDL_CONFIRM
  355.               THEN GC_PRMT_C_PACK_IDS
  356.                          ELSE GC_PRMT_A_PACK_IDS
  357.                          END,
  358.             p_cpor_id => v_cpor_id,
  359.             p_array   => v_pack_list
  360.         );
  361.  
  362.         -- DATE_FROM (дата в зоне BIS относительно зоны пользователя КП)
  363.         sc_cp_orders_pg.create_param_scalar(
  364.             p_cphp_id => CASE WHEN p_cpoh_id = GC_HANDL_CONFIRM
  365.               THEN GC_PRMT_C_DATE_FROM
  366.                          ELSE GC_PRMT_A_DATE_FROM
  367.                          END,
  368.             p_cpor_id => v_cpor_id,
  369.             p_value   => v_in_date_from
  370.         );
  371.  
  372.         -- DATE_FROM (даты в зоне BIS относительно зон абонентов)
  373.         sc_cp_orders_pg.create_param_array(
  374.             p_cphp_id => CASE WHEN p_cpoh_id = GC_HANDL_CONFIRM
  375.               THEN GC_PRMT_C_DATE_FROM_LIST
  376.                          ELSE GC_PRMT_A_DATE_FROM_LIST
  377.                          END,
  378.             p_cpor_id => v_cpor_id,
  379.             p_array   => v_in_date_from_list
  380.         );
  381.  
  382.         --------------------------------------------------------------------
  383.         -- немедленно выполняем заказ с типом "подтверждение" в новом режиме
  384.         --------------------------------------------------------------------
  385.         IF p_cpoh_id = GC_HANDL_CONFIRM THEN
  386.           -- фиксируем транзакцию
  387.           commit;
  388.  
  389.           -- выполняем заказ
  390.           sc_cp_orders_pg.execute_order_handler(
  391.               p_cpor_id => v_cpor_id
  392.           );
  393.         END IF;
  394.  
  395.         ----------------------------------
  396.         -- возвращаем идентификатор заказа
  397.         ----------------------------------
  398.         RETURN v_cpor_id;
  399.       END IF;
  400.     END reg_rate_plan_pack_change;
  401.  
  402.   -- Обрабатывает заказ на изменение ПАКЕТНОГО ТП.
  403.   FUNCTION handl_rp_and_packs_client_bis(
  404.     p_cpor_id   IN            cp_orders.cpor_id%TYPE,
  405.     p_navi_user IN            varchar2,
  406.     p_locator   IN OUT nocopy cp_order_data.xml_data%TYPE
  407.   )
  408.     RETURN NUMBER
  409.   IS
  410.     -- общие
  411.     v_order                 cp_orders%rowtype;
  412.     v_is_new_mode           BOOLEAN;
  413.     v_sum_charges_rateplan  sc_cp_bis_common_pg.gt_sum_charge_list;
  414.     v_sum_charges_packs     sc_cp_bis_common_pg.gt_sum_charge_list;
  415.     v_master_sacs_id        sc_access_levels.sacs_id%TYPE;
  416.  
  417.     -- служебные
  418.     v_result                NUMBER;
  419.     v_order_result          t_sc_cp_order_result_rec;
  420.     v_critical_err          sc_cp_common_pg.array_number;
  421.     v_xml_doc               cp_order_data.xml_data%TYPE;
  422.     C_SAVEPOINT             constant varchar2(30) := $$plsql_unit;
  423.     v_curr_subs_or_status   varchar2(9);
  424.     v_ok_subs_count         pls_integer;
  425.     v_partial_subs_count    pls_integer;
  426.     v_subs_rownums          cp_tb_number;
  427.     v_common_number_list    sc_cp_common_pg.array_number;
  428.     v_idx                   binary_integer;
  429.     v_idx_2                 binary_integer;
  430.     v_xml_detail            CLOB;
  431.  
  432.     -- дополнительные
  433.     v_subs_list             sc_cp_common_pg.array_number;
  434.     v_rtpl_id               rate_plans.rtpl_id%TYPE;
  435.     v_rtpl_already_on       BOOLEAN;
  436.     v_in_date_from          DATE;
  437.     v_in_date_from_list     sc_cp_common_pg.array_date;
  438.     v_tariff_options_source sc_kernel.gt_tariff_options_to_order_rec;
  439.  
  440.     -- специальные абонентские
  441.     v_clnt_id               clients.clnt_id%TYPE;
  442.     v_msisdn                number_sets.msisdn%TYPE;
  443.     v_dummy_date_from       DATE;
  444.     v_charge_total          NUMBER; --итоговая
  445.     v_charge_rateplan       NUMBER; --для ТП
  446.     v_charge_rateplan_tf    NUMBER;
  447.     v_tariff_options_result sc_kernel.gt_tariff_options_of_order_rec;
  448.  
  449.  
  450.     PROCEDURE fill_nested_table(
  451.       p_tn    OUT cp_tb_number,
  452.       p_array IN  sc_kernel.ids_array
  453.     )
  454.     IS
  455.       i binary_integer;
  456.       j binary_integer;
  457.     BEGIN
  458.       p_tn := cp_tb_number();
  459.       p_tn.extend(p_array.COUNT);
  460.       -- преобразуем ассоциативный массив во вложенную таблицу
  461.       i := p_array.FIRST;
  462.       j := p_tn.FIRST;
  463.       while i IS NOT NULL loop
  464.         p_tn(j) := p_array(i);
  465.         i := p_array.NEXT(i);
  466.         j := p_tn.NEXT(j);
  467.       END loop;
  468.     END fill_nested_table;
  469.  
  470.  
  471.     FUNCTION check_mandatory_option_error(
  472.       p_rtpl_id               rate_plans.rtpl_id%TYPE,
  473.       p_tariff_options_result sc_kernel.gt_tariff_options_of_order_rec
  474.     )
  475.       RETURN BOOLEAN
  476.     IS
  477.  
  478.       v_packs_appended    sc_kernel.ids_array;               -- список идентификаторов уже подключенных (до заказа) пакетов ?
  479.       v_packs_to_append   sc_kernel.gt_sbs_pack_order_list;  -- список подключаемых пакетов с зависимостями
  480.       -- sbs_packs_to_append
  481.       v_pack_order_rec    sc_kernel.gt_sbs_pack_order_rec;
  482.  
  483.       v_tn_packs          cp_tb_number;
  484.       i                   binary_integer;
  485.       j                   binary_integer;
  486.       res                 NUMBER;
  487.  
  488.       BEGIN
  489.  
  490.         v_packs_appended := p_tariff_options_result.sbs_packs_already_appended;
  491.         v_packs_to_append := p_tariff_options_result.sbs_packs_to_append;
  492.  
  493.         -- копируем опции to_append в v_packs_appended
  494.         j := v_packs_appended.COUNT;
  495.         i := v_packs_to_append.FIRST;
  496.         while i IS NOT NULL loop
  497.           v_pack_order_rec := v_packs_to_append(i);
  498.           v_packs_appended(j) := v_pack_order_rec.source_id;
  499.           j := v_packs_appended(j);
  500.           i := v_packs_to_append.NEXT(i);
  501.         END loop;
  502.  
  503.         -- преобразуем ассоциативный массив во вложенную таблицу
  504.         fill_nested_table(
  505.           p_tn => v_tn_packs,
  506.           p_array => v_packs_appended);
  507.  
  508.         -- проверка обязательных опций
  509.         SELECT COUNT(*)
  510.           INTO res
  511.           FROM (SELECT sbog.sbog_id, COUNT(tp.column_value)
  512.                   FROM sc_business_objects sbo
  513.                   INNER JOIN sc_business_obj_to_groups sbotg ON sbo.sbo_id = sbotg.sbo_sbo_id
  514.                   INNER JOIN sc_business_object_groups sbog  ON sbotg.sbog_sbog_id=sbog.sbog_id
  515.                   INNER JOIN packs p ON p.pack_id=sbo.obj_id1 AND sbo.sbot_sbot_id=2
  516.                   LEFT JOIN TABLE(v_tn_packs) tp ON tp.column_value = p.pack_id
  517.                  WHERE p.rtpl_rtpl_id=p_rtpl_id AND sbog.mandatory_yn='Y'
  518.                  GROUP BY sbog.sbog_id
  519.                  HAVING COUNT(tp.column_value) = 0) a;
  520.         IF res <> 0 THEN
  521.           RETURN TRUE;
  522.         END IF;
  523.  
  524.         -- проверка "исключающих" опций
  525.         SELECT COUNT(*)
  526.           INTO res
  527.           FROM (SELECT sbog.sbog_id, COUNT(tp.column_value)
  528.                   FROM sc_business_objects sbo
  529.                   INNER JOIN sc_business_obj_to_groups sbotg ON sbo.sbo_id = sbotg.sbo_sbo_id
  530.                   INNER JOIN sc_business_object_groups sbog  ON sbotg.sbog_sbog_id=sbog.sbog_id
  531.                   INNER JOIN packs p ON p.pack_id=sbo.obj_id1 AND sbo.sbot_sbot_id=2
  532.                   LEFT JOIN TABLE(v_tn_packs) tp ON tp.column_value = p.pack_id
  533.                  WHERE p.rtpl_rtpl_id=p_rtpl_id AND sbog.exclusive_yn='Y'
  534.                  GROUP BY sbog.sbog_id
  535.                  HAVING COUNT(tp.column_value) > 1) b;
  536.  
  537.         IF res <> 0 THEN
  538.           RETURN TRUE;
  539.         END IF;
  540.  
  541.         RETURN FALSE;
  542.       END check_mandatory_option_error;
  543.  
  544.     -- Получает список заказов в виде XML структуры.
  545.     FUNCTION get_order_list_as_xml(
  546.       p_root_tag          IN varchar2,
  547.       p_row_tag           IN varchar2                         := 'ITEM',
  548.       p_date_tag          IN varchar2                         := 'DATE',
  549.       p_dep_app_tag       IN varchar2                         := 'DEP_APP',
  550.       p_dep_app_serv_tag  IN varchar2                         := 'SERVS_DEP_APP',
  551.       p_dep_del_tag       IN varchar2                         := 'DEP_DEL',
  552.       p_dep_del_serv_tag  IN varchar2                         := 'SERVS_DEP_DEL',
  553.       p_obj_tag           IN varchar2                         := 'ID',
  554.       p_chrg_tag          IN varchar2                         := 'CHRG',
  555.       p_included_tag      IN varchar2                         := 'INCLUDED_IN_DEP',
  556.       p_order_list        IN sc_kernel.gt_sbs_pack_order_list
  557.     )
  558.       RETURN CLOB
  559.     IS
  560.       v_idx binary_integer;
  561.       v_xml CLOB;
  562.       BEGIN
  563.         v_idx := p_order_list.FIRST;
  564.         while v_idx IS NOT NULL loop
  565.           v_xml := v_xml || sc_cp_orders_pg.get_obj_as_xml(
  566.               p_tag => p_row_tag,
  567.               p_obj =>
  568.               sc_cp_orders_pg.get_obj_as_xml(
  569.                   p_tag => p_obj_tag,
  570.                   p_obj => p_order_list(v_idx).source_id
  571.               ) ||
  572.               sc_cp_orders_pg.get_obj_as_xml(
  573.                   p_tag => p_date_tag,
  574.                   p_obj => p_order_list(v_idx).opr_date
  575.               ) ||
  576.               sc_cp_orders_pg.get_obj_list_as_xml(
  577.                   p_root_tag => p_dep_app_tag,
  578.                   p_obj_tag  => p_obj_tag,
  579.                   p_obj_list => p_order_list(v_idx).packs_dep_append
  580.               ) ||
  581.               sc_cp_orders_pg.get_obj_list_as_xml(
  582.                   p_root_tag => p_dep_app_serv_tag,
  583.                   p_obj_tag  => p_obj_tag,
  584.                   p_obj_list => p_order_list(v_idx).servs_dep_append
  585.               ) ||
  586.               sc_cp_orders_pg.get_obj_list_as_xml(
  587.                   p_root_tag => p_dep_del_tag,
  588.                   p_obj_tag  => p_obj_tag,
  589.                   p_obj_list => p_order_list(v_idx).packs_dep_delete
  590.               ) ||
  591.               sc_cp_orders_pg.get_obj_list_as_xml(
  592.                   p_root_tag => p_dep_del_serv_tag,
  593.                   p_obj_tag  => p_obj_tag,
  594.                   p_obj_list => p_order_list(v_idx).servs_dep_delete
  595.               ) ||
  596.               sc_cp_orders_pg.get_obj_as_xml(
  597.                   p_tag => p_chrg_tag,
  598.                   p_obj => p_order_list(v_idx).charge
  599.               ) ||
  600.               sc_cp_orders_pg.get_obj_as_xml(
  601.                   p_tag => p_included_tag,
  602.                   p_obj => CASE WHEN p_order_list(v_idx).included_in_dep THEN 1 END
  603.               )
  604.           );
  605.           v_idx := p_order_list.NEXT(v_idx);
  606.         END loop;
  607.  
  608.         RETURN sc_cp_orders_pg.get_obj_as_xml(
  609.             p_tag => p_root_tag,
  610.             p_obj => v_xml
  611.         );
  612.       END get_order_list_as_xml;
  613.  
  614.     -- Получает список заказов в виде XML структуры.
  615.     FUNCTION get_error_list_as_xml(
  616.       p_root_tag        IN varchar2,
  617.       p_row_tag         IN varchar2                         := 'ITEM',
  618.       p_type_tag        IN varchar2                         := 'TYPE',
  619.       p_src_id_tag      IN varchar2                         := 'SRC_ID',
  620.       p_lnk_err_id_tag  IN varchar2                         := 'LNK_ERR_CODE',
  621.       p_lnk_id_tag      IN varchar2                         := 'LNK_ID',
  622.       p_lnk_serv_id_tag IN varchar2                         := 'LNK_SERV_ID',
  623.       p_lnk_date_tag    IN varchar2                         := 'LNK_DATE',
  624.       p_error_list      IN sc_kernel.gt_sbs_pack_error_list
  625.     )
  626.       RETURN CLOB
  627.     IS
  628.       v_idx binary_integer;
  629.       v_xml CLOB;
  630.       BEGIN
  631.         v_idx := p_error_list.FIRST;
  632.         while v_idx IS NOT NULL loop
  633.           v_xml := v_xml || sc_cp_orders_pg.get_obj_as_xml(
  634.               p_tag => p_row_tag,
  635.               p_obj =>
  636.               sc_cp_orders_pg.get_obj_as_xml(
  637.                   p_tag => p_type_tag,
  638.                   p_obj => p_error_list(v_idx).error_type
  639.               ) ||
  640.               sc_cp_orders_pg.get_obj_as_xml(
  641.                   p_tag => p_src_id_tag,
  642.                   p_obj => p_error_list(v_idx).source_id
  643.               ) ||
  644.               sc_cp_orders_pg.get_obj_as_xml(
  645.                   p_tag => p_lnk_err_id_tag,
  646.                   p_obj => p_error_list(v_idx).linked_err_code
  647.               ) ||
  648.               sc_cp_orders_pg.get_obj_as_xml(
  649.                   p_tag => p_lnk_id_tag,
  650.                   p_obj => p_error_list(v_idx).linked_pack_id
  651.               ) ||
  652.               sc_cp_orders_pg.get_obj_as_xml(
  653.                   p_tag => p_lnk_serv_id_tag,
  654.                   p_obj => p_error_list(v_idx).linked_serv_id
  655.               ) ||
  656.               sc_cp_orders_pg.get_obj_as_xml(
  657.                   p_tag => p_lnk_date_tag,
  658.                   p_obj => p_error_list(v_idx).linked_date
  659.               )
  660.           );
  661.           v_idx := p_error_list.NEXT(v_idx);
  662.         END loop;
  663.  
  664.         RETURN sc_cp_orders_pg.get_obj_as_xml(
  665.             p_tag => p_root_tag,
  666.             p_obj => v_xml
  667.         );
  668.       END get_error_list_as_xml;
  669.  
  670.     BEGIN
  671.       -- ===================================================================================================================
  672.       -- получаем/формируем параметры заказа
  673.       -- ===================================================================================================================
  674.  
  675.       --------
  676.       -- общие
  677.       --------
  678.       --всегда новый режим
  679.       v_is_new_mode := TRUE;
  680.  
  681.       -- все параметры
  682.       sc_cp_orders_pg.get_order_common_params(
  683.           p_cpor_id   => p_cpor_id,
  684.           p_navi_user => p_navi_user,
  685.           p_order     => v_order
  686.       );
  687.  
  688.       -- проверяем тип обработчика
  689.       IF v_order.cpoh_cpoh_id NOT IN (GC_HANDL_CONFIRM, GC_HANDL_ACTION) THEN
  690.         -- неверный тип обработчика заказа (error_code: 150080007)
  691.         sc_cp_orders_pg.write_fatal_error(
  692.             p_cpor_id => p_cpor_id,
  693.             p_err     => sc_cp_common_pg.err_order_handl_not_found,
  694.             cl        => v_xml_doc
  695.         );
  696.         sc_cp_common_pg.raise_custom_error(
  697.             error => sc_cp_common_pg.err_order_handl_not_found
  698.         );
  699.       END IF;
  700.  
  701.       -- УД владельца заказа (по типу ВКК)
  702.       v_master_sacs_id := sc_cp_orders_pg.get_order_client_sacs_id(
  703.           p_cpor_id => p_cpor_id
  704.       );
  705.  
  706.       ------------
  707.       -- служебные
  708.       ------------
  709.  
  710.       -- инициализируем результат обработки заказа КП
  711.       v_order_result := t_sc_cp_order_result_rec(
  712.           version                => '3.0',
  713.           subs_order_result_list => t_sc_cp_subs_order_result_list(),
  714.           sum_charge             => CASE WHEN v_order.cpoh_cpoh_id = GC_HANDL_CONFIRM THEN 0 END
  715.       );
  716.  
  717.       -- заполняем массив критических (общих, независимых от конкретного абонента) ошибок при обработке абонента
  718.       -- в новом режиме все ошибки некритические
  719.       v_critical_err.DELETE;
  720.  
  721.       -- инициализируем количество обработанных абонентов без ошибок
  722.       v_ok_subs_count := 0;
  723.       v_partial_subs_count := 0;
  724.  
  725.       BEGIN
  726.         -- PACK_ID
  727.         sc_cp_orders_pg.get_param_array(
  728.             p_cpor_id => p_cpor_id,
  729.             p_cphp_id => CASE WHEN v_order.cpoh_cpoh_id = GC_HANDL_CONFIRM
  730.               THEN GC_PRMT_C_PACK_IDS
  731.                          ELSE GC_PRMT_A_PACK_IDS
  732.                          END,
  733.             p_value   => v_common_number_list
  734.         );
  735.         EXCEPTION WHEN NO_DATA_FOUND THEN
  736.         v_common_number_list := sc_cp_common_pg.empty_array_number;
  737.       END;
  738.  
  739.       -----------------
  740.       -- дополнительные
  741.       -----------------
  742.       BEGIN
  743.         -- SUBS_ID
  744.         sc_cp_orders_pg.get_param_array(
  745.             p_cpor_id   => p_cpor_id,
  746.             p_cphp_id   => CASE WHEN v_order.cpoh_cpoh_id = GC_HANDL_CONFIRM
  747.               THEN GC_PRMT_C_SUBS_IDS
  748.                            ELSE GC_PRMT_A_SUBS_IDS
  749.                            END,
  750.             p_value     => v_subs_list,
  751.             p_mandatory => TRUE
  752.         );
  753.         -- получаем упорядоченный список с номерами элементов
  754.         sc_cp_orders_pg.get_sorted_param_array(
  755.             p_cpor_id => p_cpor_id,
  756.             p_cphp_id => CASE WHEN v_order.cpoh_cpoh_id = GC_HANDL_CONFIRM
  757.               THEN GC_PRMT_C_SUBS_IDS
  758.                          ELSE GC_PRMT_A_SUBS_IDS
  759.                          END,
  760.             p_value   => v_subs_list,
  761.             p_rownums => v_subs_rownums
  762.         );
  763.  
  764.         -- RTPL_ID
  765.         sc_cp_orders_pg.get_param_scalar(
  766.             p_cpor_id => p_cpor_id,
  767.             p_cphp_id => CASE WHEN v_order.cpoh_cpoh_id = GC_HANDL_CONFIRM
  768.               THEN GC_PRMT_C_RTPL_ID
  769.                          ELSE GC_PRMT_A_RTPL_ID
  770.                          END,
  771.             p_value   => v_rtpl_id
  772.         );
  773.         IF v_rtpl_id IS NULL THEN
  774.           -- не задан ТП (error_code: 150190003)
  775.           sc_cp_orders_pg.write_fatal_error(
  776.               p_cpor_id => p_cpor_id,
  777.               p_err     => sc_cp_bis_common_pg.err_param_rtpl_empty,
  778.               cl        => v_xml_doc
  779.           );
  780.           sc_cp_common_pg.raise_custom_error(
  781.               error => sc_cp_bis_common_pg.err_param_rtpl_empty
  782.           );
  783.         END IF;
  784.  
  785.         ----------------------------------------------------------------------------------------------------
  786.         -- PROCEDURE
  787.         --Тип операции всегда на подключение тарифных опций
  788.         v_tariff_options_source.sbs_opr_type := sc_cp_bis_ord_pack_pg.GC_OPR_TYPE_ON;
  789.  
  790.         -- записываем в соответствующий параметр результата обработки заказа КП
  791.         v_order_result.opr_type := sc_cp_bis_ord_pack_pg.GC_OPR_TYPE_NAME_ON;
  792.  
  793.         -- данные по пакетам
  794.         v_tariff_options_source.process_packages := TRUE;
  795.  
  796.         -- все пакеты, кроме контентных
  797.         v_tariff_options_source.packs_return_type := -1;
  798.  
  799.         -- преобразовываем в массив базовой подсистемы
  800.         IF v_common_number_list.COUNT > 0 THEN
  801.           v_idx := v_common_number_list.FIRST;
  802.           while v_idx IS NOT NULL loop
  803.             v_tariff_options_source.pack_ids(v_idx) := v_common_number_list(v_idx);
  804.             --
  805.             v_idx := v_common_number_list.NEXT(v_idx);
  806.           END loop;
  807.  
  808.           -- DATE_FROM (даты в зоне BIS относительно зон абонентов)
  809.           sc_cp_orders_pg.get_param_array(
  810.               p_cpor_id   => p_cpor_id,
  811.               p_cphp_id   => CASE WHEN v_order.cpoh_cpoh_id = GC_HANDL_CONFIRM
  812.                 THEN GC_PRMT_C_DATE_FROM_LIST
  813.                              ELSE GC_PRMT_A_DATE_FROM_LIST
  814.                              END,
  815.               p_value     => v_in_date_from_list,
  816.               p_rownums   => v_subs_rownums, -- поэлементная согласованность со списком абонентов
  817.               p_mandatory => v_is_new_mode -- для нового режима параметр обязательный
  818.           );
  819.  
  820.         END IF;
  821.  
  822.  
  823.         ----------------------------------------------------------------------------------------------------
  824.  
  825.         -- DATE_FROM (дата в зоне BIS относительно зоны пользователя КП)
  826.         sc_cp_orders_pg.get_param_scalar(
  827.             p_cpor_id => p_cpor_id,
  828.             p_cphp_id => CASE WHEN v_order.cpoh_cpoh_id = GC_HANDL_CONFIRM
  829.               THEN GC_PRMT_C_DATE_FROM
  830.                          ELSE GC_PRMT_A_DATE_FROM
  831.                          END,
  832.             p_value   => v_in_date_from
  833.         );
  834.         --Дублирование в сущность тарифных опций
  835.         v_tariff_options_source.sbs_date_from := v_in_date_from;
  836.  
  837.         -- признак выполнения только проверок (режим подтверждения)
  838.         IF v_order.cpoh_cpoh_id = GC_HANDL_CONFIRM THEN
  839.           v_tariff_options_source.check_only := TRUE;
  840.         END IF;
  841.  
  842.         -- для нового режима указываем пошаговую обработку элементов заказа
  843.         v_tariff_options_source.process_step_by_step := TRUE;
  844.  
  845.         -- признак возможности частичного выполнения (после проверок) заказа
  846.         IF v_order.cpoh_cpoh_id = GC_HANDL_ACTION THEN
  847.           v_tariff_options_source.sbs_exec_partial := v_order.processing_mode = sc_cp_orders_pg.GC_PM_PARTIAL;
  848.         END IF;
  849.  
  850.         exception
  851.         WHEN NO_DATA_FOUND THEN
  852.         -- параметр не найден (error_code: 150080001)
  853.         sc_cp_orders_pg.write_fatal_error(
  854.             p_cpor_id => p_cpor_id,
  855.             p_err     => sc_cp_common_pg.err_param_not_found,
  856.             cl        => v_xml_doc
  857.         );
  858.         sc_cp_common_pg.raise_custom_error(
  859.             error => sc_cp_common_pg.err_param_not_found
  860.         );
  861.       END;
  862.  
  863.  
  864.       -- ===================================================================================================================
  865.       -- выполняем заказ
  866.       -- ===================================================================================================================
  867.  
  868.       -- в цикле по каждому абоненту
  869.       v_idx := v_subs_list.FIRST;
  870.       while v_idx IS NOT NULL loop
  871.         -- устанавливаем точку сохранения для обеспечения целостности изменений по абоненту
  872.         v_curr_subs_or_status := sc_cp_orders_pg.set_curr_subs_or_status(
  873.             p_or_status => sc_cp_orders_pg.GC_SUB_OR_OK,
  874.             p_savepoint => C_SAVEPOINT
  875.         );
  876.  
  877.         ------------------------------------------
  878.         -- выполняем основные действия по абоненту
  879.         ------------------------------------------
  880.         BEGIN
  881.           -----------------------------------------------
  882.           -- определяем специальные абонентские параметры
  883.           -----------------------------------------------
  884.  
  885.           -- клиент абонента
  886.           v_clnt_id := sc_kernel.get_clnt_by_subs(
  887.               p_subs_id => v_subs_list(v_idx)
  888.           );
  889.  
  890.           -- MSISDN абонента
  891.           v_msisdn  := sc_kernel.get_msisdn_by_subs_id(
  892.               p_subs_id => v_subs_list(v_idx)
  893.           );
  894.  
  895.           -- дата в зоне BIS относительно зоны абонента
  896.           -- (эта дата может быть не определена, в этом случае берем дату относительно зоны пользователя КП)
  897.           IF v_in_date_from_list.COUNT > 0 THEN
  898.             v_in_date_from := v_in_date_from_list(v_idx);
  899.           END IF;
  900.  
  901.           ----------------------------------------------------------------
  902.           -- списки дат заказа в старом режиме
  903.           IF
  904.           -- новая дата
  905.           v_in_date_from_list.COUNT > 0
  906.           -- либо дата одна, но нужно заполнить в первый раз
  907.           OR v_idx = v_subs_list.FIRST
  908.           THEN
  909.             v_idx_2 := v_tariff_options_source.pack_ids.FIRST;
  910.             while v_idx_2 IS NOT NULL loop
  911.               v_tariff_options_source.pack_dates(v_idx_2) := v_tariff_options_source.sbs_date_from;
  912.               --
  913.               v_idx_2 := v_tariff_options_source.pack_ids.NEXT(v_idx_2);
  914.             END loop;
  915.           END IF;
  916.           ----------------------------------------------------------------
  917.  
  918.           ----------------------
  919.           -- выполняем обработку
  920.           ----------------------
  921.           -- В случае, если у абонента еще не подключен запрашиваемый ТП
  922.           v_rtpl_already_on := v_rtpl_id = sc_kernel.get_current_rate_plan( p_subs_id => v_subs_list(v_idx), p_date => v_in_date_from );
  923.           IF NOT v_rtpl_already_on THEN
  924.  
  925.             -- выполняем пользовательские дополнительные проверки
  926.             sc_cp_bis_user_func_pg.up_check_order_rateplan(
  927.                 p_clnt_id   => v_clnt_id,
  928.                 p_subs_id   => v_subs_list(v_idx),
  929.                 p_rtpl_id   => v_rtpl_id,
  930.                 p_date_from => v_in_date_from
  931.             );
  932.             -- вызываем базовую процедуру...
  933.             IF v_order.cpoh_cpoh_id = GC_HANDL_CONFIRM THEN
  934.               -- подтверждения смены ТП
  935.               sc_custom.i_change_rate_plan_confirm_1(
  936.                   p_subs_id         => v_subs_list(v_idx),
  937.                   rtpl_id           => v_rtpl_id,
  938.                   subscriber_msisdn => v_msisdn,
  939.                   in_date_from      => v_in_date_from,
  940.                   date_from         => v_dummy_date_from,
  941.                   charge            => v_charge_rateplan,
  942.                   charge_tf         => v_charge_rateplan_tf,
  943.                   p_bis_tz          => 1 -- даты передаются в зоне сервера BIS
  944.               );
  945.               -- проверяем достаточность средств на счету клиента для списания накопленной суммы
  946.               sc_cp_bis_common_pg.check_balance_for_oper_list(
  947.                   p_clnt_id     => v_clnt_id,
  948.                   p_subs_id     => v_subs_list(v_idx),
  949.                   p_sum_charges => v_sum_charges_rateplan,
  950.                   p_charge      => v_charge_rateplan
  951.               );
  952.             ELSE
  953.               -- выполнение смены ТП
  954.               sc_custom.i_change_rate_plan_1(
  955.                   p_clnt_id         => v_clnt_id,
  956.                   p_subs_id         => v_subs_list(v_idx),
  957.                   rtpl_id           => v_rtpl_id,
  958.                   subscriber_msisdn => v_msisdn,
  959.                   p_navi_user       => v_order.navi_user,
  960.                   date_from         => v_in_date_from,
  961.                   charge            => v_charge_rateplan,
  962.                   charge_tf         => v_charge_rateplan_tf,
  963.                   p_bis_tz          => 1 -- даты передаются в зоне сервера BIS
  964.               );            
  965.             END IF;
  966.  
  967.           END IF;
  968.  
  969.           ----------Блок тарифных опций --------------------
  970.           -- выполняем пользовательские дополнительные проверки
  971.           -- (в цикле по каждому пакету)
  972.           v_idx_2 := v_tariff_options_source.pack_ids.FIRST;
  973.           while v_idx_2 IS NOT NULL loop
  974.             sc_cp_bis_user_func_pg.up_check_order_pack(
  975.                 p_clnt_id   => v_clnt_id,
  976.                 p_subs_id   => v_subs_list(v_idx),
  977.                 p_pack_id   => v_tariff_options_source.pack_ids(v_idx_2),
  978.                 p_date_from => v_tariff_options_source.sbs_date_from,
  979.                 p_operation => v_tariff_options_source.sbs_opr_type
  980.             );
  981.             --
  982.             v_idx_2 := v_tariff_options_source.pack_ids.NEXT(v_idx_2);
  983.           END loop;
  984.  
  985.           -- вызываем базовую процедуру...
  986.           -- подтверждения/изменения тарифных опций
  987.           sc_custom.order_tariff_options(
  988.               p_clnt_id         => v_clnt_id,
  989.               p_subs_id         => v_subs_list(v_idx),
  990.               p_rtpl_id         => v_rtpl_id,
  991.               p_master_sacs_id  => v_master_sacs_id,
  992.               p_in_tz           => 1,
  993.               p_navi_user       => v_order.navi_user,
  994.               p_sum_corp_charge => sc_cp_bis_common_pg.get_charge_for_oper_list(
  995.                   p_clnt_id     => v_clnt_id,
  996.                   p_sum_charges => v_sum_charges_packs
  997.               ),
  998.               --
  999.               p_order_source    => v_tariff_options_source,
  1000.               --
  1001.               p_order_result    => v_tariff_options_result
  1002.           );
  1003.  
  1004.           --------------------------------------------------
  1005.  
  1006.           ----------------------------------------------------------------------------
  1007.           -- выполняем дополнительные проверки результата выполнения базовой процедуры
  1008.           ----------------------------------------------------------------------------
  1009.           /*
  1010.           -- Требования ФС_60772 не подразумевают данную проверку, но она будет введена позже.
  1011.           -- проверка соответствия отключаемых/подключаемых опций бизнес-логике
  1012.           if check_mandatory_option_error(
  1013.               p_rtpl_id => v_rtpl_id,
  1014.               p_tariff_options_result => v_tariff_options_result) then
  1015.             sc_cp_common_pg.raise_custom_error(
  1016.                 error => sc_cp_common_pg.err_create_order
  1017.             );
  1018.           end if;
  1019.           */
  1020.           -- недоступность, коллизии, автоматическое дополнительное отключение/подключение
  1021.           -- записываем информацию по ТП
  1022.           v_xml_detail := sc_cp_orders_pg.get_obj_as_xml(
  1023.               p_tag => 'RATEPLAN',
  1024.               p_obj => (sc_cp_orders_pg.get_obj_as_xml(
  1025.                             p_tag => 'ID',
  1026.                             p_obj => v_rtpl_id
  1027.                         ) ||
  1028.                         sc_cp_orders_pg.get_obj_as_xml(
  1029.                             p_tag => 'STATUS',
  1030.                             p_obj => CASE WHEN v_rtpl_already_on THEN GC_RTPL_UNCHANGED ELSE v_curr_subs_or_status END
  1031.                         ) ||
  1032.                         sc_cp_orders_pg.get_obj_as_xml(
  1033.                             p_tag => 'CHARGE',
  1034.                             p_obj => nvl(v_charge_rateplan, 0)
  1035.                         ))
  1036.           );
  1037.  
  1038.           -- формируем детализацию результата в виде XML структуры
  1039.           v_xml_detail := v_xml_detail ||
  1040.                           -- уже подключенные и отключенные услуги
  1041.                           sc_cp_orders_pg.get_obj_list_as_xml(
  1042.                               p_root_tag => 'PACKS_ALREADY_APPENDED',
  1043.                               p_obj_list => v_tariff_options_result.sbs_packs_already_appended
  1044.                           ) ||
  1045.                           sc_cp_orders_pg.get_obj_list_as_xml(
  1046.                               p_root_tag => 'PACKS_ALREADY_DELETED',
  1047.                               p_obj_list => v_tariff_options_result.sbs_packs_already_deleted
  1048.                           ) ||
  1049.                           -- подключаемые и отключаемые услуги
  1050.                           get_order_list_as_xml(
  1051.                               p_root_tag   => 'PACKS_TO_APPEND',
  1052.                               p_order_list => v_tariff_options_result.sbs_packs_to_append
  1053.                           ) ||
  1054.                           get_order_list_as_xml(
  1055.                               p_root_tag   => 'PACKS_TO_DELETE',
  1056.                               p_order_list => v_tariff_options_result.sbs_packs_to_delete
  1057.                           ) ||
  1058.                           -- ошибки
  1059.                           get_error_list_as_xml(
  1060.                               p_root_tag   => 'PACKS_APPEND_ERROR',
  1061.                               p_error_list => v_tariff_options_result.sbs_pack_append_errors
  1062.                           ) ||
  1063.                           get_error_list_as_xml(
  1064.                               p_root_tag   => 'PACKS_DELETE_ERROR',
  1065.                               p_error_list => v_tariff_options_result.sbs_pack_delete_errors
  1066.                           )
  1067.           ;
  1068.  
  1069.           -- определяем признак частичной обработки заказа
  1070.           -- либо если тарифные опции не выбраны
  1071.           IF v_tariff_options_result.sbs_result_status IN (sc_kernel.GC_ORD_RS_PARTIALLY, sc_kernel.GC_ORD_RS_ERROR) THEN
  1072.             v_curr_subs_or_status := sc_cp_orders_pg.set_curr_subs_or_status(
  1073.                 p_or_status => sc_cp_orders_pg.GC_SUB_OR_PARTIALLY,
  1074.                 p_savepoint => C_SAVEPOINT
  1075.             );
  1076.           END IF;
  1077.           -- для нового режима накапливаем стоимость начислений на корпоративном счете
  1078.  
  1079.           IF v_curr_subs_or_status != sc_cp_orders_pg.GC_SUB_OR_ERROR THEN
  1080.             sc_cp_bis_common_pg.add_charge_for_oper_list(
  1081.                 p_clnt_id     => v_clnt_id,
  1082.                 p_sum_charges => v_sum_charges_packs,
  1083.                 p_charge      => v_tariff_options_result.charge_common
  1084.             );
  1085.           END IF;
  1086.  
  1087.           exception
  1088.           WHEN others THEN
  1089.           -- обрабатываем ошибки с сохранением результата
  1090.           /*
  1091.           1 - тарифный план не доступен
  1092.           2 - у ТП есть обязателные группы без выбранных опций
  1093.           */
  1094.           IF NOT sc_cp_orders_pg.brake_error_handler(
  1095.               p_cpor_id           => p_cpor_id,
  1096.               p_sqlcode           => sqlcode,
  1097.               p_sqlerrm           => sqlerrm,
  1098.               p_critical_err      => v_critical_err,
  1099.               p_subs_id           => v_subs_list(v_idx),
  1100.               p_clnt_id           => v_clnt_id,
  1101.               xml_doc             => v_xml_doc,
  1102.               p_subs_order_result => v_order_result.subs_order_result_list
  1103.           )
  1104.           THEN
  1105.             --             прокидываем исключение для критической ошибки (для отката основной транзакции)
  1106.             --             raise;
  1107.             -- откатываем изменения по текущему абоненту для продолжения обработки по абонентам (ошибка не критическая)
  1108.             v_curr_subs_or_status := sc_cp_orders_pg.set_curr_subs_or_status(
  1109.                 p_or_status => sc_cp_orders_pg.GC_SUB_OR_ERROR,
  1110.                 p_savepoint => C_SAVEPOINT
  1111.             );
  1112.           END IF;
  1113.  
  1114.         END;
  1115.         ----------------------------------------------------------------------
  1116.         -- выполняем дополнительные действия по успешно обработанному абоненту
  1117.         ----------------------------------------------------------------------
  1118.         IF v_curr_subs_or_status != sc_cp_orders_pg.GC_SUB_OR_ERROR THEN
  1119.           -- для режима подтверждения...
  1120.           -- суммируем стоимость
  1121.           v_charge_total := nvl(v_charge_rateplan, 0) + nvl(v_tariff_options_result.charge, 0);
  1122.           v_order_result.sum_charge := v_order_result.sum_charge + nvl(
  1123.               v_charge_total,
  1124.               0
  1125.           );
  1126.  
  1127.           -- записываем информацию по успешно обработанному абоненту
  1128.           v_order_result.subs_order_result_list.extend;
  1129.           v_order_result.subs_order_result_list(v_order_result.subs_order_result_list.LAST) :=
  1130.           t_sc_cp_subs_order_result_rec(
  1131.               subs_id => v_subs_list(v_idx),
  1132.               STATUS  => v_curr_subs_or_status,
  1133.               detail  => v_xml_detail,
  1134.               charge  => v_charge_total
  1135.           );
  1136.  
  1137.           -- записываем прогресс по успешно обработанным абонентам
  1138.           sc_cp_orders_pg.change_order_progress(
  1139.               p_cpor_id       => p_cpor_id,
  1140.               p_subs_all_cnt  => v_subs_list.COUNT,
  1141.               p_subs_curr_cnt => v_ok_subs_count + 1
  1142.           );
  1143.           IF v_curr_subs_or_status = sc_cp_orders_pg.GC_SUB_OR_OK THEN
  1144.             v_ok_subs_count := v_ok_subs_count + 1;
  1145.           elsif v_curr_subs_or_status = sc_cp_orders_pg.GC_SUB_OR_PARTIALLY THEN
  1146.             v_partial_subs_count := v_partial_subs_count + 1;
  1147.           END IF;
  1148.         END IF;
  1149.  
  1150.         -- переходим к обработке следующего абонента
  1151.         v_idx := v_subs_list.NEXT(v_idx);
  1152.       END loop;
  1153.  
  1154.  
  1155.       -- ===================================================================================================================
  1156.       -- формируем/записываем результат заказа
  1157.       -- ===================================================================================================================
  1158.  
  1159.       --------------------------------------------
  1160.       -- формируем идентификатор результата заказа
  1161.       --------------------------------------------
  1162.       v_result := CASE
  1163.                   -- все абоненты обработаны без ошибок
  1164.                   WHEN v_ok_subs_count = v_subs_list.COUNT
  1165.                     THEN sc_cp_orders_pg.GC_OR_OK
  1166.  
  1167.                   -- либо только часть абонентов обработана с ошибками и запрошен был режим "выполнить по всем, кому возможно",
  1168.                   -- либо был запрошен режим немедленного выполнения заказа с типом "подтверждение"
  1169.                   WHEN (
  1170.                          ( v_ok_subs_count > 0 OR v_partial_subs_count > 0)
  1171.                          AND v_order.processing_mode = sc_cp_orders_pg.GC_PM_PARTIAL
  1172.                        )
  1173.                        OR (
  1174.                          v_order.cpoh_cpoh_id = GC_HANDL_CONFIRM
  1175.                        )
  1176.                     THEN sc_cp_orders_pg.GC_OR_PARTIALLY
  1177.  
  1178.                   -- в остальных случаях считаем, что заказ не выполнился и все изменения необходимо откатить
  1179.                   ELSE sc_cp_orders_pg.GC_OR_ERROR
  1180.                   END;
  1181.  
  1182.       ----------------------------------------
  1183.       -- записываем результат обработки заказа
  1184.       ----------------------------------------
  1185.  
  1186.       -- получаем результат в виде XML
  1187.       sc_cp_orders_pg.get_order_result_as_xml(
  1188.           p_order_result => v_order_result,
  1189.           p_xml_data     => v_xml_doc
  1190.       );
  1191.  
  1192.       -- сохраняем XML...
  1193.       IF v_result = sc_cp_orders_pg.GC_OR_ERROR THEN
  1194.         -- в автономной транзакции, так как далее произойдет откат всех изменений в текущей транзакции
  1195.         sc_cp_orders_pg.write_to_clob_auto_trn(
  1196.             p_cpor_id => p_cpor_id,
  1197.             p_xml_doc => v_xml_doc
  1198.         );
  1199.       ELSE
  1200.         -- в текущей транзакции
  1201.         sc_cp_orders_pg.write_to_clob(
  1202.             rclob => p_locator,
  1203.             tclob => v_xml_doc
  1204.         );
  1205.       END IF;
  1206.  
  1207.       ---------------------------------------------
  1208.       -- возвращаем идентификатор результата заказа
  1209.       ---------------------------------------------
  1210.       RETURN v_result;
  1211.     END handl_rp_and_packs_client_bis;
  1212.  
  1213.   -- Обрабатывает заказ на изменение ТП (маршрутизатор по типу клиента).
  1214.   FUNCTION handl_rate_plan_pack_change(
  1215.     p_cpor_id   IN            cp_orders.cpor_id%TYPE,
  1216.     p_cpct_id   IN            cp_client_type.cpct_id%TYPE,
  1217.     p_bis_id    IN            cp_clients.bis_id%TYPE,
  1218.     p_navi_user IN            varchar2,
  1219.     p_locator   IN OUT nocopy cp_order_data.xml_data%TYPE
  1220.   )
  1221.     RETURN NUMBER
  1222.   IS
  1223.     BEGIN
  1224.       RETURN handl_rp_and_packs_client_bis(
  1225.           p_cpor_id   => p_cpor_id,
  1226.           p_navi_user => p_navi_user,
  1227.           p_locator   => p_locator
  1228.       );
  1229.     END handl_rate_plan_pack_change;
  1230.  
  1231.   -- Создает запись зависимости опции от тарифного плана
  1232.   -- на выходе возвращает статус:
  1233.   -- 0 - зависимость успешно создана;
  1234.   -- 1 - не найден тарифный план;
  1235.   -- 2 - не найдена опция;
  1236.   -- 3 - такая зависимость уже существует.
  1237.   FUNCTION connect_pack_to_rtpl(p_rtpl_id  IN sc_business_objects.sbo_id%TYPE,
  1238.                                 p_pack_id  IN sc_business_objects.sbo_id%TYPE)
  1239.     RETURN NUMBER
  1240.   IS
  1241.     v_rtpl_id sc_business_objects.sbo_id%TYPE;
  1242.     v_pack_id sc_business_objects.sbo_id%TYPE;
  1243.     v_existed_count NUMBER;
  1244.     BEGIN
  1245.       BEGIN
  1246.         SELECT sbo_id INTO v_rtpl_id FROM sc_business_objects WHERE sbot_sbot_id = 1 AND sbo_id = p_rtpl_id;
  1247.         exception
  1248.           WHEN NO_DATA_FOUND THEN
  1249.           RETURN 1;
  1250.       END;
  1251.       BEGIN
  1252.         SELECT sbo_id INTO v_pack_id FROM sc_business_objects WHERE sbot_sbot_id = 2 AND sbo_id = p_pack_id;
  1253.         exception
  1254.           WHEN NO_DATA_FOUND THEN
  1255.           RETURN 2;
  1256.       END;
  1257.  
  1258.       SELECT COUNT(*) INTO v_existed_count FROM cp_sbo_to_sbo WHERE sbo_sbo_id = v_pack_id AND sbo_sbo_id_parent = v_rtpl_id;
  1259.       IF v_existed_count = 0 THEN
  1260.         INSERT INTO cp_sbo_to_sbo(sbo_sbo_id, sbo_sbo_id_parent)
  1261.           VALUES (v_pack_id, v_rtpl_id);
  1262.         RETURN 0;
  1263.       ELSE
  1264.         RETURN 3;
  1265.       END IF;
  1266.     END connect_pack_to_rtpl;
  1267.  
  1268. END sc_cp_bis_ord_rateplan_pack_pg;
  1269. /
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement