-- 05_sys_code_objects.sql
-- Create SYS custom code objects (packages, procedures, functions)
-- Source: backup/05_sys_code_objects.sql
-- Note: UTL_MAIL and UTL_MAIL_INTERNAL excluded (Oracle built-in)

-- ============================================================================
-- AUTH_PACK Package Specification
-- ============================================================================
CREATE OR REPLACE NONEDITIONABLE PACKAGE "SYS"."AUTH_PACK" is

  -- Author  : MARIUS.ATANASIU
  -- Created : 11/5/2005 9:58:27 AM
  -- Purpose :

  procedure verifica_program;

  procedure verifica_licenta(v_sid IN NUMBER, v_program IN VARCHAR2);
  procedure verifica_licenta_luna(v_an   IN NUMBER,
                                  v_luna IN NUMBER,
                                  v_tip  IN NUMBER);
  procedure verifica_numar_firme;

  procedure adauga_serie(V_ID_PROGRAM IN NUMBER,
                         V_SERIE      IN VARCHAR2,
                         V_ID_UTILAD  IN NUMBER);

  procedure sterge_serie(V_ID_PROGRAM IN NUMBER, V_ID_UTILS IN NUMBER);

  procedure verifica_serie(V_ID_PROGRAM IN NUMBER, V_SERIE IN RAW);

  function selecteaza_serie(V_ID_PROGRAM IN NUMBER) return varchar2;

  function selecteaza_nr_util(V_ID_PROGRAM IN NUMBER) return number;

  function selecteaza_data_val(V_ID_PROGRAM IN NUMBER) return date;

  function decripteaza_serie(V_ID_PROGRAM IN NUMBER,
                             V_SERIE      IN RAW,
                             V_DATAORA    IN DATE) return varchar2;

  function decripteaza_nr_util(V_SERIEC IN VARCHAR2) return number;

  function decripteaza_data_val(V_SERIEC IN VARCHAR2, V_ZI IN VARCHAR2)
    return date;

  function hextodec(V_HEXA IN VARCHAR2) return number;

  function dectohex(V_NUMAR IN NUMBER) return varchar2;

end AUTH_PACK;
/

-- ============================================================================
-- AUTH_PACK Package Body
-- ============================================================================
CREATE OR REPLACE NONEDITIONABLE PACKAGE BODY "SYS"."AUTH_PACK" is
  -- versiune 2025-01-14-01

  ------------------------------------------------------------------------------
  -- ISTORIC MODIFICARI:
  -- 2025-01-14: Migrare Oracle 10g -> Oracle 21c Express
  --             - Inlocuit DBMS_OBFUSCATION_TOOLKIT.DES3Decrypt cu DBMS_CRYPTO.DECRYPT
  --             - Folosit ENCRYPT_3DES_2KEY (cheie 16 bytes) + CHAIN_CBC + PAD_ZERO
  --             - Modificari in: decripteaza_serie()
  ------------------------------------------------------------------------------

  procedure verifica_program is
    v_program VARCHAR2(256);
    v_modul   VARCHAR2(256);
    v_sid     NUMBER(16);
  begin
    begin
      SELECT sid, UPPER(TRIM(program)), UPPER(TRIM(module))
        INTO v_sid, v_program, v_modul
        FROM v$session
       WHERE audsid = USERENV('SESSIONID')
         AND audsid != 0
         AND rownum = 1
         AND STATUS <> 'KILLED';
PINFO('1 LOGIN ' || V_PROGRAM || ' USER ' || USER, 'SYS.AUTH');

      IF v_program not in ('ROASTART.EXE',
                           'PLSQLDEV.EXE',
                           'ROAGEN.EXE',
                           'ROASUPORT.EXE',
                           'EXPDP.EXE',
                           'IMPDP.EXE',
                           'APSNET_WP.EXE',
                           'W3WP.EXE',
                           'RUBY.EXE',
                           'SQLPLUS.EXE',
                           'TASKS.EXE',
                          'VFP9.EXE',
                          'ROAEFACTURA.EXE',
                           'WEBDEV.WEBSERVER.EXE',
                           'ROA2COCACOLA.EXE') and
         user not in ('SYS',
                      'SYSTEM',
                      'DBSNMP',
                      'CTXSYS',
                      'MDSYS',
                      'DIP',
                      'SYSMAN',
                      'WMSYS') THEN
PINFO('2 LOGIN ' || V_PROGRAM || ' USER ' || USER, 'SYS.AUTH');
        IF v_program <> v_modul THEN
          RAISE_APPLICATION_ERROR(-20000, 'Acces interzis!');
        END IF;
PINFO('3 LOGIN ' || V_PROGRAM || ' USER ' || USER, 'SYS.AUTH');
        IF NOT V_PROGRAM LIKE 'ORACLE%' THEN
            auth_pack.verifica_licenta(v_sid, v_program);
        END IF;
PINFO('4 LOGIN ' || V_PROGRAM || ' USER ' || USER, 'SYS.AUTH');
      END IF;
    exception
      when NO_DATA_FOUND then
        v_program := Null;
    end;

  end;
  -------------------------------------------------------------------------------------
  -- VERIFICA_LICENTA
  -- LA LOGIN IN BAZA DE DATE SE VERIFICA DACA ESTE LICENTA PENTRU PROGRAM, SI PENTRU NUMARUL DE  UTILIZATORI PE PROGRAM DUPA IP
  procedure verifica_licenta(v_sid IN NUMBER, v_program IN VARCHAR2) is

    v_serie        VARCHAR2(256);
    v_seriec       VARCHAR2(256);
    v_nr_util      NUMBER(5);
    v_utilizatori  NUMBER(5);
    v_nume_program SYN_NOM_PROGRAME.DENUMIRE%TYPE;
    v_id_program   CONTAFIN_ORACLE.NOM_PROGRAME.ID_PROGRAM%TYPE;
    v_dataora      DATE;
    v_data_val     DATE;
    v_zi           VARCHAR2(2);

  begin
    V_NUME_PROGRAM := TRIM(REPLACE(v_program, '.EXE'));
    begin
      SELECT A.ID_PROGRAM, B.SERIE, B.DATAORA
        INTO V_ID_PROGRAM, V_SERIE, V_DATAORA
        FROM SYN_NOM_PROGRAME A
        LEFT JOIN AUTH_SERII B
          ON A.ID_PROGRAM = B.ID_PROGRAM
       WHERE UPPER(TRIM(A.DENUMIRE)) = V_NUME_PROGRAM
         AND B.STERS = 0;

    exception
      WHEN NO_DATA_FOUND THEN
PINFO('1 LOGIN ' || V_PROGRAM || ' USER ' || USER, 'SYS.AUTH2');
        RAISE_APPLICATION_ERROR(-20000,
                                'Nu aveti licenta pentru ' ||
                                V_NUME_PROGRAM || '!' || CHR(13) || CHR(10) ||
                                ' Licenta poate fi introdusa prin programul ROASUPORT!');
    end;
PINFO('2 LOGIN ' || V_PROGRAM || ' USER ' || USER, 'SYS.AUTH2');
    v_zi          := LPAD(extract(day from v_dataora), 2, '0');
    v_seriec      := auth_pack.decripteaza_serie(v_id_program,
                                                 v_serie,
                                                 v_dataora);
    v_utilizatori := auth_pack.decripteaza_nr_util(v_seriec);
    v_data_val    := auth_pack.decripteaza_data_val(v_seriec, v_zi);

    IF v_utilizatori > 0 THEN
      -- numar cate ip-uri (client_info) distincte cu programul v_program sunt conectate
      -- exceptand ip-ul curent
      -- astfel se poate conecta de pe acelasi ip, cu acelasi program de mai multe ori
      -- fara sa conteze la numarul utilizatorilor conectati
      SELECT COUNT(DISTINCT client_info)
        INTO v_nr_util
        FROM v$session
       WHERE UPPER(TRIM(PROGRAM)) = v_program
         AND SID != v_sid
         and status <> 'KILLED'
         and nvl(client_info, 'x') <> sys_context('userenv', 'ip_address');

      IF v_nr_util >= v_utilizatori THEN
        RAISE_APPLICATION_ERROR(-20000,
                                'Ati depasit numarul de licente (' ||
                                v_utilizatori || ') pentru programul ' ||
                                v_nume_program || ' !' || CHR(13) ||
                                CHR(10) ||
                                ' Licenta poate fi reinnoita prin programul ROASUPORT!');
      END IF;
    ELSE
      RAISE_APPLICATION_ERROR(-20000,
                              'Seria introdusa pentru acest program nu este corecta!' ||
                              CHR(13) || CHR(10) ||
                              ' Licenta poate fi modificata prin programul ROASUPORT!');
    END IF;
    PINFO('3 LOGIN ' || V_PROGRAM || ' USER ' || USER, 'SYS.AUTH2');
  end;
  -------------------------------------------------------------------------------------
  -- VERIFICA_LICENTA_LUNA
  -- LA DESCHIDEREA DE LUNA NOUA SE VERIFICA DACA ESTE LICENTA PENTRU LUNA NOUA (TRIGGER LA INSERT INTO CALENDAR)
  procedure verifica_licenta_luna(v_an   IN NUMBER,
                                  v_luna IN NUMBER,
                                  v_tip  IN NUMBER) is

    v_serie         VARCHAR2(256);
    v_seriec        VARCHAR2(256);
    v_nume_program1 SYN_NOM_PROGRAME.DENUMIRE%TYPE := 'ROASTART';
    v_nume_program2 SYN_NOM_PROGRAME.DENUMIRE%TYPE := 'ROASAL';
    v_id_program    CONTAFIN_ORACLE.NOM_PROGRAME.ID_PROGRAM%TYPE;
    v_dataora       DATE;
    v_data_val      DATE;
    v_zi            VARCHAR2(2);

  begin
    begin
      SELECT A.ID_PROGRAM, B.SERIE, B.DATAORA
        INTO V_ID_PROGRAM, V_SERIE, V_DATAORA
        FROM SYN_NOM_PROGRAME A
        LEFT JOIN AUTH_SERII B
          ON A.ID_PROGRAM = B.ID_PROGRAM
       WHERE UPPER(TRIM(A.DENUMIRE)) =
             DECODE(V_TIP, 1, V_NUME_PROGRAM1, 2, V_NUME_PROGRAM2, 'XYZ')
            -- daca parametrul nu e 1 sau 2, atunci trebuie sa dea eroare
         AND B.STERS = 0;

    exception
      WHEN NO_DATA_FOUND THEN
        RAISE_APPLICATION_ERROR(-20000,
                                'Nu aveti licenta pentru deschiderea de luna noua!' ||
                                CHR(13) || CHR(10) ||
                                ' Licenta poate fi introdusa prin programul ROASUPORT!');
    end;

    v_zi       := LPAD(extract(day from v_dataora), 2, '0');
    v_seriec   := auth_pack.decripteaza_serie(v_id_program,
                                              v_serie,
                                              v_dataora);
    v_data_val := auth_pack.decripteaza_data_val(v_seriec, v_zi);

    IF v_data_val < TO_DATE(v_an || v_luna, 'YYYYMM') THEN
      RAISE_APPLICATION_ERROR(-20000,
                              'Licenta pentru acest program a expirat!' ||
                              CHR(13) || CHR(10) ||
                              ' Licenta poate fi reinnoita prin programul ROASUPORT!');
    END IF;

  end;
  -------------------------------------------------------------------------------------
  -- VERIFICA_NUMAR_FIRME
  -- LA CREAREA UNEI FIRME NOI SE VERIFICA DACA SE DEPASESTE NUMARUL DE FIRME DIN LICENTA
  procedure verifica_numar_firme is

    v_serie        VARCHAR2(256);
    v_seriec       VARCHAR2(256);
    v_nume_program SYN_NOM_PROGRAME.DENUMIRE%TYPE := 'ROASTART';
    v_id_program   CONTAFIN_ORACLE.NOM_PROGRAME.ID_PROGRAM%TYPE;
    v_dataora      DATE;
    V_NR_MAX_FIRME NUMBER(10) := 0;
    V_NR_FIRME     NUMBER(10) := 0;

  begin
    begin
      SELECT A.ID_PROGRAM, B.SERIE, B.DATAORA
        INTO V_ID_PROGRAM, V_SERIE, V_DATAORA
        FROM SYN_NOM_PROGRAME A
        LEFT JOIN AUTH_SERII B
          ON A.ID_PROGRAM = B.ID_PROGRAM
       WHERE UPPER(TRIM(A.DENUMIRE)) = V_NUME_PROGRAM
         AND B.STERS = 0;

    exception
      WHEN NO_DATA_FOUND THEN
        RAISE_APPLICATION_ERROR(-20000,
                                'Nu aveti licenta pentru deschiderea unei firme noi!' ||
                                CHR(13) || CHR(10) ||
                                ' Licenta poate fi introdusa prin programul ROASUPORT!');
    end;

    v_seriec       := auth_pack.decripteaza_serie(v_id_program,
                                                  v_serie,
                                                  v_dataora);
    V_NR_MAX_FIRME := auth_pack.decripteaza_nr_util(V_SERIEC);

    SELECT COUNT(*)
      INTO V_NR_FIRME
      FROM SYN_NOM_FIRME
     WHERE STERS = 0
       AND NVL(ID_MAMA, 0) = 0;

    IF V_NR_FIRME >= V_NR_MAX_FIRME THEN
      RAISE_APPLICATION_ERROR(-20000,
                              'Aveti licenta pentru maxim ' ||
                              V_NR_MAX_FIRME || ' firme (' || V_NR_FIRME ||
                              ' firme deja definite)!' || CHR(13) ||
                              CHR(10) ||
                              ' Licenta poate fi introdusa prin programul ROASUPORT!');
    END IF;

  end;
  -------------------------------------------------------------------------------------
  procedure adauga_serie(V_ID_PROGRAM IN NUMBER,
                         V_SERIE      IN VARCHAR2,
                         V_ID_UTILAD  IN NUMBER) is
    V_ID_SERIE AUTH_SERII.ID_SERIE%TYPE;
    V_SERIER   AUTH_SERII.SERIE%TYPE;
    eroare_de_conversie EXCEPTION;
    PRAGMA EXCEPTION_INIT(eroare_de_conversie, -6502);
  begin
    BEGIN
      V_SERIER := HEXTORAW(V_SERIE);
    EXCEPTION
      WHEN eroare_de_conversie THEN
        RAISE_APPLICATION_ERROR(-20000, 'Aceasta serie nu este valida!');
    END;

    auth_pack.verifica_serie(V_ID_PROGRAM, V_SERIER);

    SELECT SEQ_AUTH_SERII.NEXTVAL INTO V_ID_SERIE FROM DUAL;

    INSERT INTO AUTH_SERII
      (ID_SERIE, ID_PROGRAM, SERIE, ID_UTIL)
    VALUES
      (V_ID_SERIE, V_ID_PROGRAM, V_SERIER, V_ID_UTILAD);

  end;
  -------------------------------------------------------------------------------------
  procedure sterge_serie(V_ID_PROGRAM IN NUMBER, V_ID_UTILS IN NUMBER) is
  begin
    UPDATE AUTH_SERII
       SET STERS = 1, ID_UTILS = V_ID_UTILS, DATAORAS = SYSDATE
     WHERE ID_PROGRAM = V_ID_PROGRAM
       AND STERS = 0;
  end;
  -------------------------------------------------------------------------------------
  function selecteaza_serie(V_ID_PROGRAM IN NUMBER) return varchar2 is
    V_SERIE  AUTH_SERII.SERIE%TYPE;
    V_SERIEC VARCHAR2(256);
    eroare_de_conversie EXCEPTION;
    PRAGMA EXCEPTION_INIT(eroare_de_conversie, -6502);
  begin
    begin
      SELECT SERIE
        INTO V_SERIE
        FROM AUTH_SERII
       WHERE ID_PROGRAM = V_ID_PROGRAM
         AND STERS = 0;
    exception
      when NO_DATA_FOUND then
        V_SERIE := NULL;
    end;

    BEGIN
      V_SERIEC := TRIM(RAWTOHEX(V_SERIE));
    EXCEPTION
      WHEN eroare_de_conversie THEN
        V_SERIEC := NULL;
    END;

    return V_SERIEC;
  end;
  -------------------------------------------------------------------------------------
  function selecteaza_nr_util(V_ID_PROGRAM IN NUMBER) return number is
    V_SERIE          AUTH_SERII.SERIE%TYPE;
    V_DATAORA        DATE;
    V_NR_UTILIZATORI NUMBER(4);
    V_SERIEC         VARCHAR2(64);
  begin
    begin
      SELECT SERIE, DATAORA
        INTO V_SERIE, V_DATAORA
        FROM AUTH_SERII
       WHERE ID_PROGRAM = V_ID_PROGRAM
         AND STERS = 0;

      V_SERIEC := auth_pack.decripteaza_serie(V_ID_PROGRAM,
                                              V_SERIE,
                                              V_DATAORA);

      V_NR_UTILIZATORI := auth_pack.decripteaza_nr_util(V_SERIEC);

    exception
      when NO_DATA_FOUND then
        V_NR_UTILIZATORI := 0;
    end;

    return V_NR_UTILIZATORI;
  end;
  -------------------------------------------------------------------------------------
  function selecteaza_data_val(V_ID_PROGRAM IN NUMBER) return date is
    V_SERIE    AUTH_SERII.SERIE%TYPE;
    V_DATAORA  DATE;
    V_DATA_VAL DATE;
    V_SERIEC   VARCHAR2(64);
    V_ZI       VARCHAR2(2);
  begin
    begin

      SELECT SERIE, DATAORA
        INTO V_SERIE, V_DATAORA
        FROM AUTH_SERII
       WHERE ID_PROGRAM = V_ID_PROGRAM
         AND STERS = 0;

      V_SERIEC   := auth_pack.decripteaza_serie(V_ID_PROGRAM,
                                                V_SERIE,
                                                V_DATAORA);
      V_ZI       := LPAD(EXTRACT(DAY FROM V_DATAORA), 2, '0');
      V_DATA_VAL := auth_pack.decripteaza_data_val(V_SERIEC, V_ZI);

    exception
      when NO_DATA_FOUND then
        V_DATA_VAL := NULL;
    end;

    return V_DATA_VAL;
  end;
  -------------------------------------------------------------------------------------
  procedure verifica_serie(V_ID_PROGRAM IN NUMBER, V_SERIE IN RAW) is
    v_seriedec VARCHAR2(256);
    v_checksum NUMBER(2);
    v_suma     NUMBER(2) := 0;
  begin
    v_seriedec := auth_pack.decripteaza_serie(V_ID_PROGRAM,
                                              V_SERIE,
                                              SYSDATE);

    v_checksum := auth_pack.hextodec(substr(v_seriedec,
                                            length(v_seriedec),
                                            1));
    for i in 1 .. length(v_seriedec) - 1 loop
      v_suma := v_suma + auth_pack.hextodec(substr(v_seriedec, i, 1));
    end loop;

    if MOD(v_suma + v_checksum, 16) <> 0 then
      RAISE_APPLICATION_ERROR(-20000, 'Seria introdusa nu este valida!');
    end if;

  end;
  -------------------------------------------------------------------------------------
  function decripteaza_serie(V_ID_PROGRAM IN NUMBER,
                             V_SERIE      IN RAW,
                             V_DATAORA    IN DATE) return varchar2 is
    v_denumire  CONTAFIN_ORACLE.NOM_PROGRAME.DENUMIRE%TYPE;
    v_id_client NUMBER(4);
    v_cheie     RAW(16);
    v_serieval  RAW(256);
    v_seriedec  VARCHAR2(32);
    v_valoare   NUMBER(2);
    eroare_de_conversie EXCEPTION;
    PRAGMA EXCEPTION_INIT(eroare_de_conversie, -6502);
  begin
    IF V_SERIE IS NOT NULL THEN
      SELECT substr(a.denumire, 4, 5)
        INTO V_DENUMIRE
        FROM SYN_NOM_PROGRAME A
       WHERE A.ID_PROGRAM = V_ID_PROGRAM;

      SELECT TO_NUMBER(DETALII) INTO V_ID_CLIENT FROM AUTH_DETALII;

      v_cheie := utl_raw.cast_to_raw(RPAD(LPAD(v_id_program, 3, '0') ||
                      LPAD(v_id_client, 4, '0') ||
                      RPAD(v_denumire, 5, CHR(4)) ||
                      LPAD(to_char(v_dataora, 'IWYY'), 4, '0'),
                      16,
                      'X'));

      -- Inlocuit DBMS_OBFUSCATION_TOOLKIT.DES3Decrypt cu DBMS_CRYPTO.DECRYPT
      -- ENCRYPT_3DES_2KEY pentru chei de 16 bytes, PAD_ZERO pentru compatibilitate
      v_serieval := DBMS_CRYPTO.DECRYPT(
                       src => v_serie,
                       typ => DBMS_CRYPTO.ENCRYPT_3DES_2KEY + DBMS_CRYPTO.CHAIN_CBC + DBMS_CRYPTO.PAD_ZERO,
                       key => v_cheie
                    );

      begin
        for i in 1 .. length(v_serieval) / 2 loop
          v_valoare := to_number(substr(v_serieval, 2 * i - 1, 2));
          if v_valoare > 40 then
            v_seriedec := v_seriedec || auth_pack.dectohex(v_valoare - 31);
          else
            v_seriedec := v_seriedec || (v_valoare - 30);
          end if;
        end loop;
      exception
        when eroare_de_conversie then
          RAISE_APPLICATION_ERROR(-20100,
                                  'Seria introdusa nu este valida!');
      end;

    ELSE
      v_seriedec := NULL;
    END IF;

    RETURN v_seriedec;
  end;
  -------------------------------------------------------------------------------------
  function decripteaza_nr_util(V_SERIEC IN VARCHAR2) return number is
  begin
    IF V_SERIEC IS NOT NULL THEN
      return to_number(substr(v_seriec, 1, 4));
    ELSE
      return 0;
    END IF;
  end;
  -------------------------------------------------------------------------------------
  function decripteaza_data_val(V_SERIEC IN VARCHAR2, V_ZI IN VARCHAR2)
    return date is
    v_luna varchar2(2);
  begin
    IF V_SERIEC IS NOT NULL THEN
      v_luna := LPAD(auth_pack.hextodec(substr(v_seriec, 5, 1)), 2, '0');
      return last_day(to_date(v_luna || substr(v_seriec, 6, 2), 'MMYY'));
    ELSE
      return null;
    END IF;
  end;
  -------------------------------------------------------------------------------------
  function hextodec(V_HEXA IN VARCHAR2) return number is
    v_numar NUMBER(2);
  begin
    IF ASCII(UPPER(TRIM(V_HEXA))) BETWEEN 48 AND 57 or
       ASCII(UPPER(TRIM(V_HEXA))) BETWEEN 65 AND 70 THEN
      CASE UPPER(TRIM(V_HEXA))
        WHEN 'A' THEN
          v_numar := 10;
        WHEN 'B' THEN
          v_numar := 11;
        WHEN 'C' THEN
          v_numar := 12;
        WHEN 'D' THEN
          v_numar := 13;
        WHEN 'E' THEN
          v_numar := 14;
        WHEN 'F' THEN
          v_numar := 15;
        ELSE
          v_numar := to_number(V_HEXA);
      END CASE;
    ELSE
      RAISE_APPLICATION_ERROR(-20000, 'Caracterul nu este valid!');
    END IF;
    return v_numar;
  end;
  -------------------------------------------------------------------------------------
  function dectohex(V_NUMAR IN NUMBER) return varchar2 is
    v_hexa VARCHAR2(1);
  begin
    CASE v_numar
      WHEN 10 THEN
        v_hexa := 'A';
      WHEN 11 THEN
        v_hexa := 'B';
      WHEN 12 THEN
        v_hexa := 'C';
      WHEN 13 THEN
        v_hexa := 'D';
      WHEN 14 THEN
        v_hexa := 'E';
      WHEN 15 THEN
        v_hexa := 'F';
      ELSE
        v_hexa := to_char(V_NUMAR);
    END CASE;
    return v_hexa;
  end;

end AUTH_PACK;
/

-- ============================================================================
-- PINFO Procedure (wrapped)
-- ============================================================================
CREATE OR REPLACE NONEDITIONABLE PROCEDURE "SYS"."PINFO" wrapped
a000000
b2
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
7
d3 e7
upTW3dK2OWquAE9qYLTPkR2RYpwwgy7cmJ5qfHSKimRQCVrK0lt6JkrTw376tMBrXqprtSRs
3F59wMZSKNEfsiHE5qU4k/VLyE0GHVQOHroHCu1lLnCoJ2cL5HuwV1l13q9vshqVV+HqW8iZ
4r37EyYRJSuaK2nFOQuUu7mgwop/p/KVn2UAnzh9V6+tJBW2C4yS2jO/C9ISABHyfhn3R8gS
6w/fw6l4/Q==
/

-- ============================================================================
-- NEWSCHEMA Procedure
-- ============================================================================
CREATE OR REPLACE NONEDITIONABLE PROCEDURE "SYS"."NEWSCHEMA" (tcSchema varchar2,
                                      tnLuna   number,
                                      tnAn     number) is
  lcCommand varchar2(1000);

  lcSchemaSursa      VARCHAR2(100) := 'FIRMANOUA';
  lcSchemaDestinatie VARCHAR2(100) := tcSchema;
  lcDumpFile         VARCHAR2(100);
  lcDumpDir          VARCHAR2(100) := 'DMPDIR';
  -- lnCount            number(10);

  lcSql            varchar2(1000);
  lnAn             number := tnAn;
  lnLuna           number := tnLuna;
  ldDataI          date;
  ldDataF          date;
  lnZileLucratoare number(10) := 0;
  lnOreLucratoare  number(10) := 0;
  lnMaxAn          number(10);
  lcLocatie        varchar2(100) := 'CREARE FIRMA ' || tcSchema;

  h1           NUMBER; -- Data Pump job handle
  ind          NUMBER; -- Loop index
  percent_done NUMBER; -- Percentage of job complete
  job_state    VARCHAR2(30); -- To keep track of job state
  le           ku$_LogEntry; -- For WIP and error messages
  js           ku$_JobStatus; -- The job status from get_status
  -- jd           ku$_JobDesc; -- The job description from get_status
  sts ku$_Status; -- The status object returned by get_status
begin
  ------------------------------------------------------------------------
  -- CREATE THE USER
  ------------------------------------------------------------------------
  /*  SELECT COUNT(1)
    INTO lnCount
    FROM dba_users
   WHERE username = UPPER(tcSchema);

  IF lnCount <> 0 THEN
    EXECUTE IMMEDIATE ('DROP USER ' || tcSchema || ' CASCADE');
  END IF;*/

  lcCommand := 'create user ' || tcSchema || ' identified by ' || CASE
                 WHEN upper(tcSchema) like 'TEST%' THEN
                  '"123"'
                 ELSE
                  'ROMFASTSOFT'
               END || ' default tablespace ROA
  temporary tablespace TEMP
  profile DEFAULT';
  pinfo(lcCommand, lcLocatie);
  execute immediate lcCommand;

  ------------------------------------------------------------------------
  -- GRANT PRIVILEGIES
  ------------------------------------------------------------------------
  lcCommand := 'grant connect to ' || tcSchema;
  execute immediate lcCommand;
  lcCommand := 'grant resource to ' || tcSchema;
  execute immediate lcCommand;
  lcCommand := 'grant create materialized view to ' || tcSchema;
  execute immediate lcCommand;
  lcCommand := 'grant create procedure to ' || tcSchema;
  execute immediate lcCommand;
  lcCommand := 'grant create sequence to ' || tcSchema;
  execute immediate lcCommand;
  lcCommand := 'grant create table to ' || tcSchema;
  execute immediate lcCommand;
  lcCommand := 'grant create trigger to ' || tcSchema;
  execute immediate lcCommand;
  lcCommand := 'grant create type to ' || tcSchema;
  execute immediate lcCommand;
  lcCommand := 'grant create view to ' || tcSchema;
  execute immediate lcCommand;
  lcCommand := 'grant debug connect session to ' || tcSchema;
  execute immediate lcCommand;
  lcCommand := 'grant select any table to ' || tcSchema;
  execute immediate lcCommand;
  lcCommand := 'grant unlimited tablespace to ' || tcSchema;
  execute immediate lcCommand;

  ------------------------------------------------------------------------
  -- IMPORT DUMP
  ------------------------------------------------------------------------
  -- Create a (user-named) Data Pump job to do a "full" import (everything
  -- in the dump file without filtering).

  lcDumpFile := lcSchemaSursa || '.dmp';

  --  h1 := DBMS_DATAPUMP.OPEN('IMPORT', 'SCHEMA', NULL, lcSchemaDestinatie);
  h1 := DBMS_DATAPUMP.OPEN('IMPORT', 'SCHEMA', NULL, lcSchemaDestinatie);

  -- Specify the single dump file for the job (using the handle just returned)
  -- and directory object, which must already be defined and accessible
  -- to the user running this procedure. This is the dump file created by
  -- the export operation in the first example.

  -- DBMS_DATAPUMP.ADD_FILE(h1, lcDumpFile, lcDumpDir);

  BEGIN
    PINFO('DBMS_DATAPUMP.ADD_FILE LOG', lcLocatie);
    DBMS_DATAPUMP.ADD_FILE(handle    => h1,
                           filename  => lcSchemaDestinatie || '.log',
                           directory => 'DMPDIR',
                           filetype  => 3);

    PINFO('DBMS_DATAPUMP.ADD_FILE DMP', lcLocatie);
    DBMS_DATAPUMP.ADD_FILE(handle    => h1,
                           filename  => lcDumpFile,
                           directory => lcDumpDir,
                           filetype  => 1);

    -- A metadata remap will map all schema objects from HR to BLAKE.
    PINFO('DBMS_DATAPUMP.METADATA_REMAP', lcLocatie);
    DBMS_DATAPUMP.METADATA_REMAP(h1,
                                 'REMAP_SCHEMA',
                                 lcSchemaSursa,
                                 lcSchemaDestinatie);

    -- If a table already exists in the destination schema, skip it (leave
    -- the preexisting table alone). This is the default, but it does not hurt
    -- to specify it explicitly.

    DBMS_DATAPUMP.SET_PARAMETER(h1, 'TABLE_EXISTS_ACTION', 'SKIP');

    -- Start the job. An exception is returned if something is not set up properly.

    PINFO('DBMS_DATAPUMP.START_JOB', lcLocatie);
    DBMS_DATAPUMP.START_JOB(h1);

    ------------------------------------------------------------------------
    -- The import job should now be running. In the following loop, the job is
    -- monitored until it completes. In the meantime, progress information is
    -- displayed. Note: this is identical to the export example.

    percent_done := 0;
    job_state    := 'UNDEFINED';
    while (job_state != 'COMPLETED') and (job_state != 'STOPPED') loop
      dbms_datapump.get_status(h1,
                               dbms_datapump.ku$_status_job_error +
                               dbms_datapump.ku$_status_job_status +
                               dbms_datapump.ku$_status_wip,
                               -1,
                               job_state,
                               sts);
      js := sts.job_status;

      -- If the percentage done changed, display the new value.

      if js.percent_done != percent_done then
        pinfo('*** Job percent done = ' || to_char(js.percent_done),
              lcLocatie);
        percent_done := js.percent_done;
      end if;

      -- If any work-in-progress (WIP) or Error messages were received for the job,
      -- display them.

      if (bitand(sts.mask, dbms_datapump.ku$_status_wip) != 0) then
        le := sts.wip;
      else
        if (bitand(sts.mask, dbms_datapump.ku$_status_job_error) != 0) then
          le := sts.error;
        else
          le := null;
        end if;
      end if;
      if le is not null then
        ind := le.FIRST;
        while ind is not null loop
          --        dbms_output.put_line(le(ind).LogText);
          pinfo(le(ind).LogText, lcLocatie);
          ind := le.NEXT(ind);
        end loop;
      end if;
    end loop;

    -- Indicate that the job finished and gracefully detach from it.
    -- dbms_output.put_line('Job has completed');
    pinfo('Job has completed', lcLocatie);

    -- dbms_output.put_line('Final job state = ' || job_state);
    pinfo('Final job state = ' || job_state,
          'CREARE FIRMA ' || lcSchemaDestinatie);

    ------------------------------------------------------------------------
    -- POST IMPORT

    -- 1. actualizare calendar, sal_calendar, cote_tva
    -- CALENDAR
    lcSql := 'UPDATE ' || lcSchemaDestinatie ||
             '.CALENDAR SET ANUL = :1, LUNA = :2, AN = TO_CHAR(:3), NL = LPAD(:4, 2, ''0'')';
    PINFO(lcSql, lcLocatie);
    EXECUTE IMMEDIATE lcSql
      USING lnAn, lnLuna, lnAn, lnLuna;

    -- SAL_CALENDAR
    ldDataI := TO_DATE(lpad(lnAn, 4, '0') || lpad(lnLuna, 2, '0'), 'YYYYMM');
    ldDataF := ADD_MONTHS(ldDataI, 1) - 1;
    lcSql   := 'select ' || lcSchemaDestinatie ||
               '.pack_personal.calculeaza_nr_zile(:1, :2) FROM DUAL';
    EXECUTE IMMEDIATE lcSql
      INTO lnZileLucratoare
      USING ldDataI, ldDataF;
    lnOreLucratoare := lnZileLucratoare * 8;

    lcSql := 'UPDATE ' || lcSchemaDestinatie ||
             '.SAL_CALENDAR SET AN = :1 , LUNA = :2, ZILELUC = :3, ORESTAS = :4, ORELUC = :5';
    PINFO(lcSql, lcLocatie);
    EXECUTE IMMEDIATE lcSql
      USING lnAn, lnLuna, lnZileLucratoare, lnOreLucratoare, lnOreLucratoare;

    -- SAL_IMPOZITAR
    lcSql := 'UPDATE ' || lcSchemaDestinatie ||
             '.SAL_IMPOZITAR SET AN = :1 , LUNA = :2';
    PINFO(lcSql, lcLocatie);
    EXECUTE IMMEDIATE lcSql
      USING lnAn, lnLuna;

    -- PLCONT
    lcSql := 'SELECT max(an) as plan from ' || lcSchemaDestinatie ||
             '.PLCONT';
    PINFO(lcSql, lcLocatie);
    EXECUTE IMMEDIATE lcSql
      into lnMaxAn;
    if lnMaxAn <> lnAn then
      lcSql := 'UPDATE ' || lcSchemaDestinatie ||
               '.PLCONT SET AN = :1 WHERE AN = :2';
      PINFO(lcSql, lcLocatie);
      EXECUTE IMMEDIATE lcSql
        USING lnAn, lnMaxAn;
    end if;

    -- COTE_TVA
    lcSql := 'SELECT max(an*12+luna) from ' || lcSchemaDestinatie ||
             '.cote_tva';
    PINFO(lcSql, lcLocatie);
    EXECUTE IMMEDIATE lcSql
      into lnMaxAn;

    lcSql := 'UPDATE ' || lcSchemaDestinatie ||
             '.COTE_TVA SET AN = :1, LUNA = :2 WHERE AN*12+LUNA = :3';
    PINFO(lcSql, lcLocatie);
    EXECUTE IMMEDIATE lcSql
      USING lnAn, lnLuna, lnMaxAn;
    ------------------------------------------------------------------------
    -- 2. ACTUALIZARE SCHEMA LA ZI
    PINFO('Actualizare schema la zi...', lcLocatie);
    CONTAFIN_ORACLE.PACK_UPDATE.UpdateROA(tnUpdateApp       => 0,
                                          tnUpdateScripturi => 0,
                                          tnUpdateDatabase  => 1,
                                          tcSchemaList      => tcSchema);

  EXCEPTION
    WHEN OTHERS THEN
      PINFO(SQLERRM, lcLocatie);
      raise_application_error(-20000, SQLERRM);
  END;

  DBMS_DATAPUMP.DETACH(h1);

end NewSchema;
/

-- ============================================================================
-- UPDATESQLPLUS Procedure
-- ============================================================================
CREATE OR REPLACE NONEDITIONABLE PROCEDURE "SYS"."UPDATESQLPLUS" (tcSqlPlusPath in varchar2,
                                          tcScriptPath  in varchar2) as
lcJobName varchar2(500);
begin
  lcJobName := 'updateschema_' || to_char(sysdate, 'YYYYMMDDHH24MISS');
  dbms_scheduler.create_job(lcJobName,
                            job_action          => tcSqlPlusPath,
                            number_of_arguments => 2,
                            job_type            => 'executable',
                            enabled             => false);
  dbms_scheduler.set_job_argument_value(lcJobName, 1, '/nolog');
  dbms_scheduler.set_job_argument_value(lcJobName, 2, '@' || tcScriptPath);
  dbms_scheduler.enable(lcJobName);
end;
/

-- ============================================================================
-- NEWSCHEMAJOB Procedure
-- ============================================================================
CREATE OR REPLACE NONEDITIONABLE PROCEDURE "SYS"."NEWSCHEMAJOB" (tcSchema varchar2,
                                         tnLuna   number,
                                         tnAn     number) as
  lcJobName varchar2(500);
begin
  lcJobName := 'NEWSCHEMA_' || UPPER(tcSchema);
  dbms_scheduler.create_job(job_name            => lcJobName,
                                job_type            => 'STORED_PROCEDURE',
                                job_action          => 'NEWSCHEMA',
                                number_of_arguments => 3,
                                enabled             => false);
  dbms_scheduler.set_job_argument_value(lcJobName, 1, tcSchema);
  dbms_scheduler.set_job_argument_value(lcJobName, 2, to_char(tnLuna));
  dbms_scheduler.set_job_argument_value(lcJobName, 3, to_char(tnAn));
  dbms_scheduler.enable(lcJobName);
end NEWSCHEMAJOB;
/

-- ============================================================================
-- EXECUTESCRIPTOS Procedure
-- ============================================================================
CREATE OR REPLACE NONEDITIONABLE PROCEDURE "SYS"."EXECUTESCRIPTOS" (tcPowerShellPath in varchar2,
                            tcScriptPath     in varchar2) as
    lcJobName varchar2(500);
  begin
 lcJobName := 'exec_ps_' || SUBSTR(SYS_GUID(), 1, 8);

    DBMS_SCHEDULER.CREATE_JOB(
        job_name => lcJobName,
        job_action => tcPowerShellPath,
        number_of_arguments => 4,
        job_type => 'executable',
        enabled => FALSE
    );

    DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(lcJobName, 1, '-ExecutionPolicy');
    DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(lcJobName, 2, 'Bypass');
    DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(lcJobName, 3, '-File');
    DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(lcJobName, 4, tcScriptPath);

    DBMS_SCHEDULER.ENABLE(lcJobName);
  end ExecuteScriptOS;
/

-- ============================================================================
-- NEWSCHEMAPROGRESS Function (wrapped)
-- ============================================================================
CREATE OR REPLACE NONEDITIONABLE FUNCTION "SYS"."NEWSCHEMAPROGRESS" wrapped
a000000
b2
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
8
252 199
zxoOlwCbdojcPsGMNEX+7vG4viowgxAJ7UhGfHS5R14whrSDSgcEWXzIxarybpjrYjS1uiG9
+1zNJlbIu3JK13bwcN6yBEVbLfFgwc0GPkaZbaSp/SMtUbWKq6audu2tqMhrqajFIq/ZxhIj
RbyhiZKk8frL4h2iwYVP6fEjGunska0ZpjeOvUDdhcOmpt60PCOUWO09fPBTLoV9UZ8FnKRq
3BnqmzYpNIh3Nmox3IHh7L1+/B3ZdDkRY588x/i3cp95sH4gv78FSbxaXXG7LcR3AbIAWqKn
yd436mUq5f997PYETavFoaYaFQoUOA1e0g/DynVjNWxPRq56JQnrwP+a0i9dmz3se/CgF7o5
DdffGzEed6v0ceFecZNDvJKMnbz6AfnkKnMFeISf8Mw=
/
