 
/*------------------------------------------------------------------------
   File        : queryHandler
   Purpose     : 
   Syntax      : 
   Description : 
   Author(s)   : walter.riechsteiner
   Created     : Wed Jul 10 18:09:37 CEST 2024
   Notes       : 
 ----------------------------------------------------------------------*/

USING Progress.Json.ObjectModel.JsonObject FROM PROPATH.
USING OpenEdge.Net.HTTP.IHttpRequest FROM PROPATH.
USING OpenEdge.DataAdmin.DataAccess.UserData FROM PROPATH.

CLASS utilities.utilitiesHandler: 

PROCEDURE GetUserNameA EXTERNAL "advapi32.dll":
    DEFINE OUTPUT       PARAMETER lpUserName   AS MEMPTR.
    DEFINE INPUT-OUTPUT PARAMETER nChars       AS LONG.
    DEFINE RETURN       PARAMETER bool         AS SHORT.
END PROCEDURE.

    DEFINE VARIABLE i1        AS INTEGER   NO-UNDO.
    DEFINE VARIABLE i2        AS INTEGER   NO-UNDO.
    DEFINE VARIABLE cProgramm AS CHARACTER NO-UNDO.
    
    DEFINE VARIABLE hBuffer   AS HANDLE    NO-UNDO.

    DEFINE TEMP-TABLE ttBrowserKo LIKE browser_ko.
    DEFINE TEMP-TABLE ttViewerKo LIKE viewer_ko.

    DEFINE TEMP-TABLE ttExternefield_nameer NO-UNDO
        FIELD ctable           AS CHARACTER
        FIELD hBuffer          AS HANDLE
        FIELD cKeyfield_nameer AS CHARACTER  
        FIELD cWhere           AS CHARACTER 
        FIELD cfield_nameer    AS CHARACTER
        FIELD cDataType        AS CHARACTER 
        .
    DEFINE TEMP-TABLE twebmenu
        SERIALIZE-NAME 'menuItems'
        FIELD level1     AS INTEGER   SERIALIZE-NAME 'level1'
        FIELD level2     AS INTEGER   SERIALIZE-NAME 'level2'
        FIELD level3     AS INTEGER   SERIALIZE-NAME 'level3'
        FIELD menu_title AS CHARACTER SERIALIZE-NAME 'menu_title'
        FIELD menu_link  AS CHARACTER SERIALIZE-NAME 'menu_link'
        .
        
    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC HANDLE createExterneFieldName(
        INPUT ipctable  AS CHARACTER ,
        INPUT ipcfield_name     AS CHARACTER ,
        INPUT ipcDatatype AS CHARACTER ,
        INPUT iphttInput  AS HANDLE
        ):
        
        DEFINE VARIABLE hBuffer        AS HANDLE    NO-UNDO.
        DEFINE VARIABLE cKeyfield_name AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cKeyValue      AS CHARACTER NO-UNDO.
        
        FIND FIRST ttExternefield_nameer
            WHERE ttExternefield_nameer.ctable = ipctable NO-ERROR.
            
        DO WHILE TRUE:
            IF AVAILABLE ttExternefield_nameer THEN LEAVE.
            
            FIND _File NO-LOCK WHERE _File._File-name = ipctable NO-ERROR.
            IF NOT AVAILABLE _File THEN RETURN hBuffer.
        
            FIND FIRST _Field NO-LOCK OF _File
                WHERE _Field._Field-Name = ipcfield_name NO-ERROR.
            IF NOT AVAILABLE _Field THEN RETURN hBuffer.
        
            CREATE BUFFER hBuffer FOR TABLE ipctable.
            CREATE ttExternefield_nameer.
            ASSIGN 
                ttExternefield_nameer.ctable  = ipctable
                ttExternefield_nameer.hBuffer = hBuffer.
          
            
            FIND FIRST _Index WHERE RECID(_Index) = _File._Prime-Index NO-LOCK.
            FOR EACH _Index-Field
                WHERE _Index-Field._Index-Recid = RECID(_Index):
                FIND _Field WHERE RECID(_Field) = _Index-Field._Field-Recid.
                
                cKeyfield_name  = _Field._Field-Name.
                cKeyValue = ''.
                CASE cKeyfield_name:
                    WHEN 'company' OR
                    WHEN 'Mandant' OR
                    WHEN 'Firma'   THEN 
                        DO:
                            cKeyValue = QUOTER(iphttInput::company).
                        END.
                    WHEN 'language_id' THEN 
                        DO:
                            cKeyValue = iphttInput::language_id.
                        END.
                    WHEN 'user_name' THEN 
                        DO:
                            cKeyValue = iphttInput::user_name.
                        END.
                END CASE.
                
                IF cKeyValue <> '' THEN 
                DO:
                    CASE ipcDatatype:
                        WHEN 'character' THEN 
                            cKeyValue = QUOTER(cKeyValue).
                    END CASE.
                    
                    ttExternefield_nameer.cWhere = ttExternefield_nameer.cWhere
                        + (IF cWhere = '' THEN 'WHERE ' ELSE 'AND ')
                        + SUBSTITUTE('&1.&2 = &3':U, ipctable, cKeyfield_name, cKeyValue).
                    NEXT.
                END.
                
                ttExternefield_nameer.cKeyfield_nameer = ttExternefield_nameer.cKeyfield_nameer
                    + (IF ttExternefield_nameer.cKeyfield_nameer = '' THEN '' ELSE ';')
                    + cKeyfield_name.
            END.
            
            IF LOOKUP(ipcfield_name, ttExternefield_nameer.cfield_nameer, ';') > 0 THEN NEXT.
            ttExternefield_nameer.cfield_nameer = ttExternefield_nameer.cfield_nameer
                + (IF ttExternefield_nameer.cfield_nameer = '' THEN '' ELSE ';')
                + ipcfield_name.
            ttExternefield_nameer.cDataType = ttExternefield_nameer.cDataType
                + (IF ttExternefield_nameer.cDataType = '' THEN '' ELSE ';')
                + ipcfield_name.
             
        END.

        // DELETE OBJECT hBuffer NO-ERROR.
        
        RETURN hBuffer.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC LOGICAL createQuery(
        INPUT   httInput     AS HANDLE,
        INPUT   httBrowserKo AS HANDLE,
        OUTPUT  hQuery       AS HANDLE,
        OUTPUT  hBuffer      AS HANDLE
        ).
            
        DEFINE VARIABLE lRetVal    AS LOGICAL   NO-UNDO INIT FALSE.
        DEFINE VARIABLE cWhere     AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cAnd       AS CHARACTER NO-UNDO INIT 'WHERE'.
        DEFINE VARIABLE ctable     AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cSortField AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cDirection AS CHARACTER NO-UNDO.
        DEFINE VARIABLE iAnzRec    AS INTEGER   NO-UNDO.
        DEFINE VARIABLE iModulo    AS INTEGER   NO-UNDO.

        ctable    = httInput::table_name.
        cSortField = httBrowserKo::sortfield.
        cDirection = ''.

        IF cSortField <> '' THEN 
        DO:
            IF NUM-ENTRIES(cSortField, ':') > 1 THEN 
            DO:
                cDirection  = ENTRY(2, cSortField, ':').
                cSortField = ENTRY(1, cSortField, ':').
            END.
            IF cDirection = '' THEN cDirection = 'ASCENDING'.
        END.

        CREATE QUERY  hQuery.
        CREATE BUFFER hBuffer FOR TABLE ctable.
        hQuery:SET-BUFFERS (hBuffer).
        
        IF httInput::action = 'last' THEN 
        DO:
            cWhere = SUBSTITUTE('PRESELECT EACH &1 NO-LOCK ', httInput::table_name).
            IF httBrowserKo::lmandant THEN 
            DO:
                cWhere = cWhere + SUBSTITUTE('&1 &2.Firma = "&3" ', cAnd, httInput::table_name, httInput::company).
            END.
            hQuery:QUERY-PREPARE (cWhere).
            hQuery:QUERY-OPEN ().
            iAnzRec = hQuery:NUM-RESULTS.
            iModulo = iAnzRec MOD httBrowserKo::pagesize.
            IF iModulo > 0 THEN httBrowserKo::actualpage = (iAnzRec - (iAnzRec MOD httBrowserKo::pagesize)) / httBrowserKo::pagesize.
            ELSE                httBrowserKo::actualpage = (iAnzRec / httBrowserKo::pagesize) - 1.   
            hQuery:QUERY-CLOSE ().
        END.
        
        i1 = 0.
        cWhere = SUBSTITUTE('FOR EACH &1 NO-LOCK ', httInput::table_name).
        IF httBrowserKo::lmandant THEN 
        DO:
            cWhere = cWhere + SUBSTITUTE('&1 &2.Firma = "&3" ', cAnd, httInput::table_name, httInput::company).
            cAnd = 'AND'.
        END.
        IF cDirection = 'ASCENDING' THEN cDirection = ''.
        IF cSortField <> '' THEN cWhere = cWhere + ' BY ' + cSortField + ' ' + cDirection.
        
        MESSAGE 'cWhere-Statement = ' cWhere.
        
        hQuery:QUERY-PREPARE (cWhere).
        
        lRetVal = TRUE.        
        RETURN lRetVal.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC LOGICAL createSearchQuery(
        INPUT   httInput     AS HANDLE,
        INPUT   httBrowserKo AS HANDLE,
        OUTPUT  hQuery       AS HANDLE,
        OUTPUT  hBuffer      AS HANDLE
        ).
            
        DEFINE VARIABLE lRetVal          AS LOGICAL   NO-UNDO INIT FALSE.
        DEFINE VARIABLE cWhere           AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cAnd             AS CHARACTER NO-UNDO INIT 'WHERE'.
        DEFINE VARIABLE ctable           AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cSuchfield_name  AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cSortField       AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cDirection       AS CHARACTER NO-UNDO.
        DEFINE VARIABLE iAnzRec          AS INTEGER   NO-UNDO.
        DEFINE VARIABLE lcWortIndex      AS LONGCHAR  NO-UNDO.
        DEFINE VARIABLE ii               AS INTEGER   NO-UNDO.
        DEFINE VARIABLE ifield_nameer    AS INTEGER   NO-UNDO.
        DEFINE VARIABLE iFound           AS INTEGER   NO-UNDO.
        DEFINE VARIABLE cInhalt          AS CHARACTER NO-UNDO.
        DEFINE VARIABLE rRecid           AS RECID     NO-UNDO.
        
        DEFINE VARIABLE httTemp          AS HANDLE    NO-UNDO.
        DEFINE VARIABLE hbtable          AS HANDLE    NO-UNDO.
        DEFINE VARIABLE hqtable          AS HANDLE    NO-UNDO.
        DEFINE VARIABLE hfield_name      AS HANDLE    NO-UNDO.
        DEFINE VARIABLE hWortIndex       AS HANDLE    NO-UNDO.
        DEFINE VARIABLE hSuchfield_name  AS HANDLE    NO-UNDO.
        DEFINE VARIABLE cfield_name      AS CHARACTER NO-UNDO.
        DEFINE VARIABLE hfield_nametable AS HANDLE    NO-UNDO EXTENT 10.
        DEFINE VARIABLE cInhalttable     AS CHARACTER NO-UNDO EXTENT 10.
        DEFINE VARIABLE cString          AS CHARACTER NO-UNDO.
        DEFINE VARIABLE ix               AS INTEGER   NO-UNDO.
        DEFINE VARIABLE iy               AS INTEGER   NO-UNDO.
        DEFINE VARIABLE lQuoter          AS LOGICAL   NO-UNDO.
        
        ctable  = httInput::table_name.
        cSuchfield_name = httInput::suchfield_name.
        cSortField = httBrowserKo::sortfield.
        cDirection = ''.
        
        IF cSortField <> '' THEN 
        DO:
            IF NUM-ENTRIES(cSortField, ':') > 1 THEN 
            DO:
                cDirection = ENTRY(2, cSortField, ':').
                cSortField = ENTRY(1, cSortField, ':').
            END.
            IF cDirection = '' THEN cDirection = 'ASCENDING'.
        END.
        MESSAGE 'Suchfield_name = ' cSuchfield_name ' sortfield = ' cSortField ' Richtung = ' cDirection.
        
        CREATE TEMP-TABLE httTemp.
        httTemp:CREATE-LIKE (ctable).
        httTemp:ADD-NEW-FIELD ('ident', 'CHARACTER').
        httTemp:TEMP-TABLE-PREPARE('ttTemp').
        hBuffer = httTemp:DEFAULT-BUFFER-HANDLE.
        
        CREATE QUERY hqtable.
        CREATE BUFFER hbtable FOR TABLE ctable. 
        hqtable:SET-BUFFERS ( hbtable ).
        hWortIndex = hbtable:BUFFER-FIELD('WortIndex') NO-ERROR.
        ifield_nameer    = NUM-ENTRIES(cSuchfield_name, ' ').
        
        ASSIGN 
            hfield_nametable = ?
            cInhalttable     = ''
            ix               = 0. 
        IF NUM-ENTRIES(cSuchfield_name, '=') > 1 THEN 
        DO:
            DO ii = 1 TO NUM-ENTRIES(cSuchfield_name, ' '):
                cString = ENTRY(ii, cSuchfield_name, ' ').
                IF NUM-ENTRIES(cString, '=') > 1 THEN 
                DO:
                    cfield_name     = ENTRY(1, cString, '=').
                    hSuchfield_name = hbtable:BUFFER-FIELD(cfield_name) NO-ERROR.
                    IF NOT VALID-HANDLE(hSuchfield_name) THEN NEXT.
                    ix = ix + 1.
                    hfield_nametable  [ix] = hSuchfield_name.
                    cInhalttable[ix] = ENTRY(2, cString, '=').
                    NEXT.
                END.
                IF NOT VALID-HANDLE(hSuchfield_name) THEN NEXT.
                cInhalttable[ix] = cInhalttable[ix] + ',' + cString.
            END.
        END.
         
        cWhere = SUBSTITUTE('PRESELECT EACH &1 NO-LOCK ', ctable).
        IF httBrowserKo::lmandant THEN 
        DO:
            cWhere = cWhere + SUBSTITUTE('&1 &2.Firma = "&3" ', cAnd, ctable, httInput::company).
            cAnd = 'AND'.
        END.
        MESSAGE 'cWhere beim Suchen ' cWhere.

        hqtable:QUERY-PREPARE (cWhere).
        hqtable:QUERY-OPEN ().
        
        NEXTDATENSATZ:
        DO WHILE TRUE:
            hqtable:GET-NEXT() NO-ERROR.
            IF hqtable:QUERY-OFF-END THEN LEAVE.
            
            lcwortindex = ''.
            rRecid      = hbtable:RECID.

            DO WHILE ix > 0:
                MESSAGE 'Suchen mit bestimmtenm field_nameern' ix.
                iFound = 0.
                DO ii = 1 TO ix:
                    hfield_name     = hfield_nametable  [ii].
                    cSuchfield_name = cInhalttable[ii].
                    cInhalt   = hfield_name:BUFFER-VALUE(0) NO-ERROR.
                    IF ERROR-STATUS:ERROR THEN NEXT.
                    IF cInhalt = ?        THEN NEXT.
                    DO iy = 1 TO NUM-ENTRIES(cSuchfield_name, ','):
                        cString = ENTRY(iy, cSuchfield_name, ',').
                        MESSAGE 'Kommt der Wert ' cString 'in' cInhalt 'vor?'.
                        IF LOOKUP(cString, cInhalt, ' ') = 0 THEN NEXT.
                        iFound = iFound + 1.
                        LEAVE.
                    END.
                END.
                IF iFound < ix THEN NEXT NEXTDATENSATZ.
                LEAVE.
            END.
            
            DO WHILE ix = 0:        
                iFound = 0.
                IF VALID-HANDLE(hWortIndex) THEN 
                DO:
                    lcWortIndex = hWortIndex:BUFFER-VALUE(0).
                END.
                ELSE 
                DO:
                    DO ii = 1 TO hbtable:NUM-FIELDS:
                        hfield_name   = hbtable:BUFFER-FIELD(ii).
                        IF hfield_name:EXTENT > 0 THEN NEXT.
                        cInhalt = getBufferFieldValue(INPUT hfield_name, OUTPUT lQuoter).
                        IF cInhalt = '' THEN NEXT.
                        lcWortIndex = lcWortIndex
                            + (IF lcWortindex = '' THEN '' ELSE ' ')
                            + cInhalt.
                    END.
                END.
                
                DO ii = 1 TO ifield_nameer:
                    cInhalt = ENTRY(ii, cSuchfield_name, ' ').
                    IF INDEX(lcWortIndex, cInhalt) = 0 THEN NEXT.
                    iFound = iFound + 1.
                END.
                IF iFound < ifield_nameer THEN NEXT NEXTDATENSATZ.
                LEAVE.
            END.

            hBuffer:BUFFER-CREATE ().
            hBuffer:BUFFER-COPY (hbtable).
            hBuffer::ident = TRIM(STRING(rRecid,'>>>>>>>>9')).
        END.
        hqtable:QUERY-CLOSE ().
        DELETE OBJECT hqtable.
        
        CREATE QUERY hQuery.
        hQuery:SET-BUFFERS ( hBuffer ).
            
        cWhere = SUBSTITUTE('FOR EACH ttTemp NO-LOCK ').
        
        IF cDirection = 'ASCENDING' THEN cDirection = ''.
        IF cSortField <> '' THEN cWhere = cWhere + ' BY ' + cSortField + ' ' + cDirection.
        
        hQuery:QUERY-PREPARE (cWhere).

        lRetVal = TRUE.
                
        RETURN lRetVal.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC VOID createTemptableBrowser(
        INPUT  httInput         AS HANDLE,
        INPUT  httBrowserKo     AS HANDLE,
        OUTPUT httBrowser       AS HANDLE  
        ):
            
        DEFINE VARIABLE cfield_name AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cLabel      AS CHARACTER NO-UNDO.
        DEFINE VARIABLE httTable    AS HANDLE    NO-UNDO.
        DEFINE VARIABLE hFremdBuff  AS HANDLE    NO-UNDO.
        
        EMPTY TEMP-TABLE ttExternefield_nameer.
        
        DEFINE BUFFER bbrowser_ze FOR browser_ze.
        
        FIND FIRST browser_ze NO-LOCK
            WHERE browser_ze.company   = httInput::company
            AND   browser_ze.user_name = httInput::user_name
            AND   browser_ze.program   = httInput::program NO-ERROR.
        IF NOT AVAILABLE browser_ze THEN 
        DO:
            FIND FIRST browser_ze NO-LOCK
                WHERE browser_ze.company   = httInput::company
                AND   browser_ze.user_name = 'admin'
                AND   browser_ze.program   = httInput::program NO-ERROR.
        END.
        
        IF NOT AVAILABLE browser_ze THEN RETURN.
        
        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
            IF browser_ze.user_name <> 'admin' THEN LEAVE.
            IF httInput::user_name  =  'admin' THEN LEAVE.
            
            FOR EACH browser_ze NO-LOCK
                WHERE browser_ze.company   = httInput::company
                AND   browser_ze.user_name = 'admin'
                AND   browser_ze.program   = httInput::program:
                
                CREATE  bbrowser_ze.
                BUFFER-COPY browser_ze
                    EXCEPT  browser_ze.user_name
                    TO      bbrowser_ze
                    ASSIGN  
                    bbrowser_ze.user_name = httInput::user_name.
                RELEASE bbrowser_ze.
            END.
            LEAVE.
        END.
        
        CREATE TEMP-TABLE httTable.
        httTable:SERIALIZE-NAME = 'browser'.
        httTable:ADD-NEW-FIELD ('ident', 'CHARACTER').
        httTable:ADD-NEW-FIELD ('sel'  , 'CHARACTER').

        FOR EACH browser_ze NO-LOCK
            WHERE browser_ze.company   = httInput::company
            AND   browser_ze.user_name = httInput::user_name
            AND   browser_ze.program   = httInput::program
            
            BY browser_ze.prior:
                
            httTable:ADD-NEW-FIELD (browser_ze.field_name, 'CHARACTER').
            
            IF browser_ze.table_name <> httInput::table_name THEN 
            DO:
                hFremdBuff = createExterneFieldName (
                    INPUT browser_ze.table_name,
                    INPUT browser_ze.field_name,
                    INPUT browser_ze.field_type,
                    INPUT httInput
                    ).
            END.
        END.
        httTable:TEMP-TABLE-PREPARE ('ttBrowser').
        httBrowser = httTable:DEFAULT-BUFFER-HANDLE.
        
        httBrowser:BUFFER-CREATE ().        
        DO i1 = 1 TO httBrowser:NUM-FIELDS:
            IF i1 = 1 THEN 
            DO:
                httBrowser:BUFFER-FIELD(i1):BUFFER-VALUE = 'ident'.
                NEXT. 
            END.
            IF i1 = 2 THEN 
            DO:
                httBrowser:BUFFER-FIELD(i1):BUFFER-VALUE = 'sel'.
                NEXT. 
            END.
            cfield_name = httBrowser:BUFFER-FIELD(i1):NAME.
            FIND FIRST labeltexte NO-LOCK 
                WHERE labeltexte.company     = httInput::company
                AND   labeltexte.user_name   = httInput::user_name
                AND   labeltexte.program     = httInput::program
                AND   labeltexte.table_name  = httInput::table_name
                AND   labeltexte.field_name  = cfield_name
                AND   labeltexte.language_id = httInput::language_id NO-ERROR.
            IF NOT AVAILABLE labeltexte THEN 
            DO: 
                FIND FIRST labeltexte NO-LOCK 
                    WHERE labeltexte.company     = httInput::company
                    AND   labeltexte.program     = httInput::program
                    AND   labeltexte.table_name  = httInput::table_name
                    AND   labeltexte.field_name  = cfield_name
                    AND   labeltexte.language_id = httInput::language_id NO-ERROR.
            END.
            IF NOT AVAILABLE labeltexte THEN 
            DO:
                FIND FIRST labeltexte NO-LOCK 
                    WHERE labeltexte.company     = httInput::company
                    AND   labeltexte.table_name  = httInput::table_name
                    AND   labeltexte.field_name  = cfield_name
                    AND   labeltexte.language_id = httInput::language_id NO-ERROR.
            END.
            IF NOT AVAILABLE labeltexte THEN 
            DO:
                FIND FIRST labeltexte NO-LOCK 
                    WHERE labeltexte.company     = httInput::company
                    AND   labeltexte.field_name  = cfield_name
                    AND   labeltexte.language_id = httInput::language_id NO-ERROR.
            END.
            cLabel = (IF AVAILABLE labeltexte THEN labeltexte.headlabel ELSE cfield_name).
            httBrowser:BUFFER-FIELD(i1):buffer-VALUE(0) = cLabel + '/@/' + labeltexte.alignment.
        END.

        RETURN.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC VOID createTemptableViewer( 
        INPUT  httInput         AS HANDLE,
        INPUT  httViewerKo      AS HANDLE,
        OUTPUT httViewer        AS HANDLE  
        ):
            
        DEFINE VARIABLE cfield_name AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cLabel      AS CHARACTER NO-UNDO.
        DEFINE VARIABLE httTable    AS HANDLE    NO-UNDO.
        DEFINE VARIABLE ctable      AS CHARACTER NO-UNDO.
        DEFINE VARIABLE hBuftable   AS HANDLE    NO-UNDO.
        
        DEFINE BUFFER bviewer_ze FOR viewer_ze.
        
        FIND FIRST viewer_ze NO-LOCK
            WHERE viewer_ze.company    = httInput::company
            AND   viewer_ze.user_name  = httInput::user_name
            AND   viewer_ze.program    = httInput::program
            AND   viewer_ze.table_name = httInput::table_name NO-ERROR.
        IF NOT AVAILABLE viewer_ze THEN 
        DO:
            FIND FIRST viewer_ze NO-LOCK
                WHERE viewer_ze.company    = httInput::company
                AND   viewer_ze.user_name  = 'admin'
                AND   viewer_ze.program    = httInput::program
                AND   viewer_ze.table_name = httInput::table_name NO-ERROR.
        END.
        
        IF NOT AVAILABLE viewer_ze THEN RETURN.
        
        ctable = viewer_ze.table_name.
        
        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
            IF viewer_ze.user_name <> 'admin' THEN LEAVE.
            IF httInput::user_name =  'admin' THEN LEAVE.
            
            FOR EACH viewer_ze NO-LOCK
                WHERE viewer_ze.company    = httInput::company
                AND   viewer_ze.user_name  = 'admin'
                AND   viewer_ze.program    = httInput::program
                AND   viewer_ze.table_name = httInput::table_name:
                
                CREATE  bviewer_ze.
                BUFFER-COPY viewer_ze
                    EXCEPT  viewer_ze.user_name
                    TO      bviewer_ze
                    ASSIGN  
                    bviewer_ze.user_name = httInput::user_name.
                RELEASE bviewer_ze.
            END.
            LEAVE.
        END.
        
        CREATE BUFFER hBuftable FOR TABLE ctable.
        CREATE TEMP-TABLE httTable.
        httTable:SERIALIZE-NAME = 'viewerdaten'.

        FOR EACH viewer_ze NO-LOCK
            WHERE viewer_ze.company    = httInput::company
            AND   viewer_ze.user_name  = httInput::user_name
            AND   viewer_ze.program    = httInput::program
            AND   viewer_ze.table_name = httInput::table_name
            
            BY viewer_ze.prior:

            IF  viewer_ze.addFieldtable = ''    AND
                NOT viewer_ze.field_name BEGINS 'DUMMY' AND
                NOT viewer_ze.field_name BEGINS 'ident' THEN
                httTable:ADD-LIKE-FIELD (viewer_ze.field_name, hBuftable:BUFFER-FIELD(viewer_ze.field_name)).
            ELSE httTable:ADD-NEW-FIELD  (viewer_ze.field_name, 'CHARACTER').
        /*            MESSAGE viewer_ze.field_name ' hinzugef�gt'.*/
        END.
        httTable:TEMP-TABLE-PREPARE (ctable).
        httViewer = httTable:DEFAULT-BUFFER-HANDLE.
        
        DELETE OBJECT hBuftable.
        
        RETURN.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC LONGCHAR createWordindex(
        INPUT hBuffer AS HANDLE
        ):
        
        DEFINE VARIABLE cWordIndex AS LONGCHAR  NO-UNDO.
        
        DEFINE VARIABLE cWords     AS CHARACTER NO-UNDO.
        DEFINE VARIABLE ii         AS INTEGER   NO-UNDO.
        DEFINE VARIABLE cDatatype  AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cWord      AS CHARACTER NO-UNDO.
        

        cWords = ''.
        DO ii = 1 TO hBuffer:NUM-FIELDS:
            IF hBuffer:BUFFER-FIELD(ii):BUFFER-VALUE = ?         THEN NEXT.
            IF hBuffer:BUFFER-FIELD(ii):BUFFER-VALUE = ''        THEN NEXT.
            IF hBuffer:BUFFER-FIELD(ii):BUFFER-VALUE = '0'       THEN NEXT.
            IF INDEX(hBuffer:BUFFER-FIELD(ii):NAME, 'SHA')  > 0  THEN NEXT.
            IF INDEX(hBuffer:BUFFER-FIELD(ii):NAME, 'word') > 0  THEN NEXT.
        
            cDatatype = hBuffer:BUFFER-FIELD(ii):DATA-TYPE.
            CASE cDatatype:
                WHEN 'logical'   THEN 
                    NEXT.
                WHEN 'character' THEN 
                    cWords = cWords + ' ' + hBuffer:BUFFER-FIELD(ii):BUFFER-VALUE.
                WHEN 'integer'   THEN 
                    DO:
                        cWord  = TRIM(STRING(INTEGER(hBuffer:BUFFER-FIELD(ii):BUFFER-VALUE),'zzzzzzzz9-')).
                        cWords = cWords + ' ' + CHR(01) + cWord + CHR(01).
                    END.
                WHEN 'decimal'   THEN 
                    DO:
                        cWord  = TRIM(STRING(DECIMAL(hBuffer:BUFFER-FIELD(ii):BUFFER-VALUE),'zzzzzzzz9.9<<<-')).
                        cWords = cWords + ' ' + CHR(01) + cWord + CHR(01).
                    END.
                WHEN 'date'   THEN 
                    DO:
                        cWord  = STRING(DATE(hBuffer:BUFFER-FIELD(ii):BUFFER-VALUE),'99.99.9999').
                        cWords = cWords + ' ' + cWord.
                    END.
                OTHERWISE 
                NEXT.
            END CASE.
        END.
        cWordIndex = ''.
        cWords     = TRIM(cWords).
        cWords     = REPLACE(cWords, '  ', ' ').
        DO ii = 1 TO NUM-ENTRIES(cWords, ' '):
            cWord = TRIM(ENTRY(ii, cWords, ' ')).
            IF LOOKUP(cWord, cWordIndex, ' ') > 0 THEN NEXT.
            cWordIndex = cWordIndex + ' ' + cWord.
        END.
        cWordIndex = TRIM(cWordIndex).
        cWordIndex = REPLACE(cWordIndex, '  ', ' ').

        RETURN cWordIndex.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC VOID evaluateFile(
        INPUT  oJsonIdent AS JsonObject,
        OUTPUT cFileName  AS CHARACTER,
        OUTPUT lCompany   AS LOGICAL  ,
        OUTPUT lActive    AS LOGICAL  ,
        OUTPUT lWordindex AS LOGICAL  
        ):
            
        cFileName = ENTRY(1, oJsonIdent:GetCharacter('formId'), '_').

        DO WHILE TRUE:
            FIND FIRST Ge_MIS._File NO-LOCK 
                WHERE Ge_MIS._File._File-Name = cFileName NO-ERROR.
            IF NOT AVAILABLE Ge_MIS._File THEN LEAVE.
            
            FIND FIRST Ge_MIS._Field OF Ge_MIS._File NO-LOCK
                WHERE Ge_MIS._Field._Field-Name = 'company' NO-ERROR.
            lCompany = (IF AVAILABLE Ge_MIS._Field THEN TRUE ELSE FALSE).

            FIND FIRST Ge_MIS._Field OF Ge_MIS._File NO-LOCK
                WHERE Ge_MIS._Field._Field-Name = 'active' NO-ERROR.
            lActive = (IF AVAILABLE Ge_MIS._Field THEN TRUE ELSE FALSE).

            FIND FIRST Ge_MIS._Field OF Ge_MIS._File NO-LOCK
                WHERE Ge_MIS._Field._Field-Name = 'wordindex' NO-ERROR.
            lWordindex = (IF AVAILABLE Ge_MIS._Field THEN TRUE ELSE FALSE).
            RETURN.
        END.
        
        FIND FIRST FRAMEWORK._File NO-LOCK 
            WHERE FRAMEWORK._File._File-Name = cFileName NO-ERROR.
            
        FIND FIRST FRAMEWORK._Field OF FRAMEWORK._File NO-LOCK
            WHERE FRAMEWORK._Field._Field-Name = 'company' NO-ERROR.
        lCompany = (IF AVAILABLE FRAMEWORK._Field THEN TRUE ELSE FALSE).

        FIND FIRST FRAMEWORK._Field OF FRAMEWORK._File NO-LOCK
            WHERE FRAMEWORK._Field._Field-Name = 'active' NO-ERROR.
        lActive = (IF AVAILABLE FRAMEWORK._Field THEN TRUE ELSE FALSE).

        FIND FIRST FRAMEWORK._Field OF FRAMEWORK._File NO-LOCK
            WHERE FRAMEWORK._Field._Field-Name = 'wordindex' NO-ERROR.
        lWordindex = (IF AVAILABLE FRAMEWORK._Field THEN TRUE ELSE FALSE).
        RETURN.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC INTEGER fillBrowserTT(
        INPUT        httBrowserKo    AS HANDLE,
        INPUT        hQuery          AS HANDLE,
        INPUT        hbttInput       AS HANDLE,
        INPUT-OUTPUT httBrowser      AS HANDLE
        ):
          
        DEFINE VARIABLE hbQuery          AS HANDLE    NO-UNDO.
        DEFINE VARIABLE hfield_name      AS HANDLE    NO-UNDO.
        DEFINE VARIABLE hfield_nameRecid AS HANDLE    NO-UNDO.
        DEFINE VARIABLE cfield_name      AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cInhalt          AS CHARACTER NO-UNDO.
        DEFINE VARIABLE iAnzRec          AS INTEGER   NO-UNDO.
        DEFINE VARIABLE iSkip            AS INTEGER   NO-UNDO.
        DEFINE VARIABLE iPageSize        AS INTEGER   NO-UNDO.
        
        hQuery:QUERY-OPEN ().
        
        iSkip = httBrowserKo::actualpage * httBrowserKo::pagesize.
        hQuery:REPOSITION-FORWARD (iSkip).        
        MESSAGE 'anzahl records skip = ' iSkip.
        
        iAnzRec    = 0.
        hbQuery    = hQuery:GET-BUFFER-HANDLE ().
        hfield_nameRecid = hbQuery:BUFFER-FIELD('ident') NO-ERROR.
        iPageSize  = (IF hbttInput::suchfield_name = '' THEN httBrowserKo::pagesize ELSE 100).
        DO i1 = 1 TO iPageSize:
            hQuery:GET-NEXT() NO-ERROR.
            IF hQuery:QUERY-OFF-END THEN LEAVE.
            
            httBrowser:BUFFER-CREATE ().
            IF  hbttInput::action = 'search' AND
                i1                = 1        THEN hbttInput::ident = TRIM(STRING(INT64(hbQuery::ident),'>>>>>>>>>9')).
            IF VALID-HANDLE(hfield_nameRecid) THEN httBrowser::ident = TRIM(STRING(INT64(hbQuery::ident),'>>>>>>>>>9')).
            ELSE                             httBrowser::Ident = TRIM(STRING(hbQuery:RECID)).
            IF httBrowser::ident = hbttInput::ident THEN httBrowser::sel = 'TRUE'.
            
            DO i2 = 3 TO httBrowser:NUM-FIELDS:
                cfield_name  = httBrowser:BUFFER-FIELD(i2):NAME.
                hfield_name  = hbQuery   :BUFFER-FIELD(cfield_name) NO-ERROR.
                IF  NOT VALID-HANDLE(hfield_name) OR
                    ERROR-STATUS:ERROR      THEN 
                DO:
                    cInhalt = getFieldValueExtern(INPUT cfield_name, INPUT hbttInput, INPUT httBrowser ).
                    httBrowser:BUFFER-FIELD(i2):BUFFER-VALUE = cInhalt.
                    NEXT.
                END.
                CASE hfield_name:DATA-TYPE:
                    WHEN 'INTEGER' OR
                    WHEN 'INT64'   THEN 
                        cInhalt = TRIM(STRING(INTEGER(hfield_name:BUFFER-VALUE(0)),'->>>,>>>,>>9')).
                    WHEN 'DECIMAL' THEN 
                        cInhalt = TRIM(STRING(DECIMAL(hfield_name:BUFFER-VALUE(0)),'->>>,>>>,>>9.99<<<')).
                    WHEN 'DATE' THEN 
                        cInhalt = STRING(DATE(hfield_name:BUFFER-VALUE(0)),'99.99.9999').
                    OTHERWISE 
                    cInhalt = hfield_name:BUFFER-VALUE(0).
                END CASE.
                httBrowser:BUFFER-FIELD(i2):BUFFER-VALUE = cInhalt.
            END.
            iAnzRec = iAnzRec + 1.
        END.
        
        RETURN iAnzRec.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC VOID generateHash(
        INPUT ipAlgorithm  AS CHARACTER,
        INPUT ipPhrase     AS CHARACTER,
        INPUT ipKey        AS CHARACTER,   
        OUTPUT opERROR     AS LOGICAL,
        OUTPUT opMESSAGE   AS CHARACTER,
        OUTPUT opHash      AS CHARACTER
        ):
        
        ASSIGN  
            opERROR   = FALSE 
            opMessage = ''
            opHash    = ''.
            
        IF ipPhrase = '' OR ipPhrase = ? THEN 
        DO:
            ASSIGN 
                opERROR   = TRUE
                opMESSAGE = 'Input Error. Value not correct'.
            RETURN.
        END.
    
        opHash = HEX-ENCODE (MESSAGE-DIGEST (ipAlgorithm, ipPhrase, ipKey)).
        
        RETURN.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC VOID getActiveSelection(
        INPUT  oJsonIdent       AS JsonObject,
        INPUT  cFileName        AS CHARACTER ,
        OUTPUT cActiveSelection AS CHARACTER 
        ):
            
        DEFINE VARIABLE cForm_Id AS CHARACTER NO-UNDO.
            
        FIND userdata NO-LOCK
            WHERE userdata.user_name   = oJsonIdent:GetCharacter('user_name')
            AND   userdata.company     = oJsonIdent:GetCharacter('company')
            AND   userdata.branch      = '0000'
            AND   userdata.record_type = 'active'
            AND   userdata.section     = cFileName 
            AND   userdata.key_type    = '' NO-ERROR.
              
        IF AVAILABLE userdata THEN cActiveSelection = userdata.cfield_1.
        ELSE                       cActiveSelection = 'all'.   
        RELEASE userdata.

        RETURN.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC LOGICAL getBrowserKopf(
        INPUT  httInput     AS HANDLE,
        OUTPUT httBrowserKo AS HANDLE
        ):
        MESSAGE 'getBrowserKopf mit ' httInput::company '/' httInput::user_name '/' httInput::program '/' httInput::table_name.
        FIND FIRST browser_ko NO-LOCK
            WHERE browser_ko.company    = httInput::company
            AND   browser_ko.user_name  = httInput::user_name
            AND   browser_ko.program    = httInput::program
            AND   browser_ko.table_name = httInput::table_name NO-ERROR.
        IF NOT AVAILABLE browser_ko THEN 
        DO:
            FIND FIRST browser_ko NO-LOCK
                WHERE browser_ko.company    = httInput::company
                AND   browser_ko.user_name  = 'admin'
                AND   browser_ko.program    = httInput::program
                AND   browser_ko.table_name = httInput::table_name NO-ERROR.
        END.
        
        IF NOT AVAILABLE browser_ko THEN RETURN FALSE.
        
        httBrowserKo = TEMP-TABLE ttBrowserKo:DEFAULT-BUFFER-HANDLE.
        httBrowserKo:EMPTY-TEMP-TABLE ().
        httBrowserKo:BUFFER-CREATE ().
        httBrowserKo:BUFFER-COPY(BUFFER browser_ko:HANDLE).
        RELEASE browser_ko.
        
        RETURN TRUE.
        
    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC CHARACTER getBufferFieldValue( INPUT iphfield_name AS HANDLE, OUTPUT oplQuoter AS LOGICAL ):
        
        DEFINE VARIABLE cfield_nameInhalt AS CHARACTER NO-UNDO.

        cfield_nameInhalt = ''.
        oplQuoter   = FALSE.
        CASE iphfield_name:DATA-TYPE:
            WHEN 'CHARACTER' THEN
                ASSIGN  
                    cfield_nameInhalt = iphfield_name:BUFFER-VALUE(0)
                    oplQuoter         = TRUE.
            WHEN 'DECIMAL' OR
            WHEN 'INTEGER' THEN 
                cfield_nameInhalt = TRIM(STRING(INTEGER(iphfield_name:BUFFER-VALUE),'>>>>>>>>9')).
            WHEN 'DATE' THEN 
                cfield_nameInhalt = STRING(DATE(iphfield_name:BUFFER-VALUE),'99.99.9999').
            OTHERWISE  
            cfield_nameInhalt = iphfield_name:BUFFER-VALUE.
        END CASE.
        
        IF cfield_nameInhalt = ? THEN cfield_nameInhalt = ''. 
        
        RETURN cfield_nameInhalt.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC CHARACTER getCharDateTime(
        INPUT ipdDateTime AS DATETIME
        ):
        
        DEFINE VARIABLE cReturnValue AS CHARACTER NO-UNDO.
        DEFINE VARIABLE dDateTime    AS DATETIME  NO-UNDO.
        DEFINE VARIABLE cDateTime    AS CHARACTER NO-UNDO.

        dDateTime    = ipdDateTime. 
        cDateTime    = STRING(dDateTime,'99-99-9999THH:MM:SS').
        cReturnValue =
            STRING(YEAR(dDateTime),'9999')
            + '-'
            + STRING(MONTH(dDateTime),'99')
            + '-'
            + STRING(DAY(dDateTime),'99')
            + SUBSTRING(cDateTime,11).
            
        RETURN cReturnValue.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC HANDLE getData(
        INPUT ipoJsonIdent   AS JsonObject,
        INPUT ipcFileName    AS CHARACTER,
        INPUT ipcWherePaires AS CHARACTER 
        ):
            
        DEFINE VARIABLE cWhere      AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cWherePaire AS CHARACTER NO-UNDO.
        DEFINE VARIABLE lCompany    AS LOGICAL   NO-UNDO.
        DEFINE VARIABLE lActive     AS LOGICAL   NO-UNDO.
        DEFINE VARIABLE lWhere      AS LOGICAL   NO-UNDO INIT TRUE.
        
        DEFINE VARIABLE hBuffer     AS HANDLE    NO-UNDO.
        DEFINE VARIABLE ttTable     AS HANDLE    NO-UNDO.
        DEFINE VARIABLE httBuffer   AS HANDLE    NO-UNDO.
        DEFINE VARIABLE hQuery      AS HANDLE    NO-UNDO.
        DEFINE VARIABLE lOK         AS LOGICAL   NO-UNDO.
        
        lOK = FALSE.
        DO WHILE TRUE:
            FIND FIRST Ge_MIS._File NO-LOCK 
                WHERE Ge_MIS._File._File-Name = ipcFileName NO-ERROR.
            IF NOT AVAILABLE Ge_MIS._File THEN LEAVE.
            
            FIND FIRST Ge_MIS._Field OF Ge_MIS._File WHERE Ge_MIS._Field._Field-Name = 'company' NO-ERROR.
            lCompany = (IF AVAILABLE _Field THEN TRUE ELSE FALSE).
            FIND FIRST Ge_MIS._Field OF Ge_MIS._File WHERE Ge_MIS._Field._Field-Name = 'active' NO-ERROR.
            lActive  = (IF AVAILABLE _Field THEN TRUE ELSE FALSE).
            
            lOK = TRUE.
            LEAVE.
        END.
        
        DO WHILE NOT lOK:
            FIND FIRST FRAMEWORK._File NO-LOCK 
                WHERE FRAMEWORK._File._File-Name = ipcFileName NO-ERROR.
            IF NOT AVAILABLE FRAMEWORK._File THEN LEAVE.
            
            FIND FIRST FRAMEWORK._Field OF FRAMEWORK._File WHERE FRAMEWORK._Field._Field-Name = 'company' NO-ERROR.
            lCompany = (IF AVAILABLE _Field THEN TRUE ELSE FALSE).
            FIND FIRST FRAMEWORK._Field OF FRAMEWORK._File WHERE FRAMEWORK._Field._Field-Name = 'active' NO-ERROR.
            lActive  = (IF AVAILABLE _Field THEN TRUE ELSE FALSE).
            
            lOK = TRUE.
            LEAVE.
        END.
        
        CREATE BUFFER hBuffer FOR TABLE ipcFileName.
        CREATE TEMP-TABLE ttTable.
        ttTable:CREATE-LIKE (hBuffer).
        ttTable:TEMP-TABLE-PREPARE ('ttTable').
        httBuffer = ttTable:DEFAULT-BUFFER-HANDLE.
        
        DO i1 = 1 TO httBuffer:NUM-FIELDS:
            httBuffer:BUFFER-FIELD(i1):SERIALIZE-NAME = SUBSTITUTE('&1_&2', ipcFileName, hBuffer:BUFFER-FIELD(i1):NAME). 
        END.
        
        cWhere = SUBSTITUTE('FOR EACH &1 NO-LOCK ', ipcFileName).
        IF lCompany THEN 
        DO:
            cWhere = cWhere + (IF lWhere THEN 'WHERE ' ELSE 'AND ' ).
            cWhere = cWhere + SUBSTITUTE('&1.company = &2 ', ipcFileName, QUOTER(ipoJsonIdent:GetCharacter('company'))).
            lWhere = FALSE.
        END.
        DO i1 = 1 TO NUM-ENTRIES(ipcWherePaires, ';'):
            cWherePaire = ENTRY(i1, ipcWherePaires, ';').
            cWhere = cWhere + (IF lWhere THEN 'WHERE ' ELSE 'AND ' ) + cWherePaire + ' '.
            lWhere = FALSE.
        END.
        IF lActive THEN 
        DO:
            cWhere = cWhere + (IF lWhere THEN 'WHERE ' ELSE 'AND ' ).
            cWhere = cWhere + SUBSTITUTE('&1.active = &2 ', ipcFileName, 'TRUE').
            lWhere = FALSE.
        END.
        MESSAGE 'cWhere = ' cWhere.
        CREATE QUERY hQuery.
        hQuery:SET-BUFFERS(hBuffer).
        hQuery:QUERY-PREPARE (cWhere).
        hQuery:QUERY-OPEN ().
        hQuery:GET-FIRST ().
        DO WHILE NOT hQuery:QUERY-OFF-END:
            httBuffer:BUFFER-CREATE ().
            httBuffer:BUFFER-COPY(hBuffer).
            hQuery:GET-NEXT ().
        END.
        hQuery:QUERY-CLOSE ().
        
        DELETE OBJECT hQuery  NO-ERROR.
        DELETE OBJECT hBuffer NO-ERROR.

        RETURN httBuffer.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC VOID getErrorMessage(
        INPUT  cFehlerNo    AS CHARACTER,
        INPUT  ilanguage_id AS INTEGER,
        INPUT  cParam       AS CHARACTER,  
        OUTPUT cMessage     AS LONGCHAR 
        ):
             
        DEFINE VARIABLE lcJsonString AS CHARACTER NO-UNDO.
        DEFINE VARIABLE ii           AS INTEGER   NO-UNDO.
        DEFINE VARIABLE iNo          AS INTEGER   NO-UNDO.
        DEFINE VARIABLE cString      AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cParameter   AS CHARACTER NO-UNDO EXTENT 5.
        
        cParam = REPLACE(cParam, ',', ';').
        DO ii = 1 TO NUM-ENTRIES(cParam, ';'):
            cParameter[ii] = ENTRY(ii, cParam, ';').
            IF ii = 5 THEN LEAVE.
        END.
        lcJsonString = '(&1) ->  &2'.
        cFehlerNo = REPLACE(cFehlerNo, ',', ';').
        DO ii = 1 TO NUM-ENTRIES(cFehlerNo, ';'):
            iNo = INTEGER(ENTRY(ii, cFehlerNo, ';')).
            FIND messages NO-LOCK 
                WHERE messages.message_no  = iNo
                AND   messages.language_id = ilanguage_id NO-ERROR.
            IF NOT AVAILABLE messages THEN 
            DO:
                FIND FIRST messages NO-LOCK 
                    WHERE messages.message_no  = iNo NO-ERROR.
            END.
        
            IF NOT AVAILABLE messages THEN 
            DO:
                cString = cString
                    + (IF cString = '' THEN '' ELSE ' ')
                    + 'Systemfehler, Administrator benachrichtigen !'.
            END.
            ELSE 
            DO:
                cString = cString
                    + (IF cString = '' THEN '' ELSE ' ')
                    + messages.message_text.
            END.
        END.
        MESSAGE cString '-' cParam.
        cString = SUBSTITUTE(cString, cParameter[01], cParameter[02], cParameter[03], cParameter[04], cParameter[05]).
        MESSAGE cString.
        
        cMessage = cString.              
        
        RETURN.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC LOGICAL getField(
        INPUT httInput   AS HANDLE, 
        INPUT ctable   AS CHARACTER,
        INPUT cTabfield_name   AS CHARACTER, 
        INPUT cKeyfield_nameer AS CHARACTER,
        INPUT cKeyValues AS CHARACTER,
        INPUT htable   AS HANDLE,
        OUTPUT cInhalt   AS CHARACTER
        ):
            
        DEFINE VARIABLE hBuffer           AS HANDLE    NO-UNDO.
        DEFINE VARIABLE hfield_nameBuffer AS HANDLE    NO-UNDO.
        DEFINE VARIABLE cWhere            AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cfield_name       AS CHARACTER NO-UNDO.
        DEFINE VARIABLE hfield_name       AS HANDLE    NO-UNDO.
        DEFINE VARIABLE ii                AS INTEGER   NO-UNDO.
        DEFINE VARIABLE cString           AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cWert             AS CHARACTER NO-UNDO.
        DEFINE VARIABLE lRetVal           AS LOGICAL   NO-UNDO.
        
        CREATE BUFFER hBuffer FOR TABLE ctable.
        
        cKeyfield_nameer = REPLACE(cKeyfield_nameer, ',', ';').
        cKeyValues = REPLACE(cKeyValues, ',', ';').
        cString = ''.
        DO ii = 1 TO NUM-ENTRIES(cKeyfield_nameer, ';'):
            cString = cString 
                + (IF cString = '' THEN '' ELSE ' AND ')
                + ENTRY(ii, cKeyfield_nameer, ';')
                + ' = &1 '.
            cfield_name = ENTRY(ii, cKeyfield_nameer, ';').
            hfield_nameBuffer = hBuffer:BUFFER-FIELD(cfield_name).

            IF ENTRY(ii, cKeyValues, ';') BEGINS '@' THEN 
            DO:
                cfield_name = TRIM(SUBSTRING(ENTRY(ii, cKeyValues, ';'),02)).
                hfield_name = htable:BUFFER-FIELD(cfield_name) NO-ERROR.
                IF NOT VALID-HANDLE(hfield_name) THEN hfield_name = httInput:BUFFER-FIELD(cfield_name) NO-ERROR.
                cWert = hfield_name:BUFFER-VALUE(0).
            END.
            ELSE cWert = TRIM(ENTRY(ii, cKeyValues, ';')).
            
            CASE hfield_nameBuffer:DATA-TYPE:
                WHEN 'character' OR
                WHEN 'date'      THEN
                    cString = SUBSTITUTE(cString, QUOTER(cWert) ).
                OTHERWISE
                cString = SUBSTITUTE(cString, cWert ).
            END CASE.
        END.
        
        cWhere = SUBSTITUTE('WHERE &1 ', cString).
        MESSAGE cWhere.
        lRetVal = hBuffer:FIND-UNIQUE (cWhere, NO-LOCK).
        MESSAGE lRetVal.
        
        hfield_name   = hBuffer:BUFFER-FIELD(cTabfield_name).
        cInhalt = hfield_name:BUFFER-VALUE(0).

        MESSAGE cInhalt.

        RETURN TRUE.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC CHARACTER getFieldValueExtern(
        INPUT ipcfield_name      AS CHARACTER,
        INPUT iphttInput   AS HANDLE,
        INPUT iphttBrowser AS HANDLE
        ):
        
        DEFINE VARIABLE cfield_nameInhalt AS CHARACTER NO-UNDO INIT ''.
        
        DEFINE VARIABLE cWhere            AS CHARACTER NO-UNDO.
        DEFINE VARIABLE hBuffer           AS HANDLE    NO-UNDO.
        DEFINE VARIABLE cKeyValue         AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cKeyfield_name    AS CHARACTER NO-UNDO.
        DEFINE VARIABLE lRetVal           AS LOGICAL   NO-UNDO.
        DEFINE VARIABLE ii                AS INTEGER   NO-UNDO.
        DEFINE VARIABLE hfield_name       AS HANDLE    NO-UNDO.        
       
        FIND FIRST ttExternefield_nameer NO-LOCK
            WHERE LOOKUP(ipcfield_name, ttExternefield_nameer.cfield_nameer, ';') > 0 NO-ERROR.
        IF NOT AVAILABLE ttExternefield_nameer THEN RETURN cfield_nameInhalt.

        hBuffer = ttExternefield_nameer.hBuffer.
        cWhere  = ttExternefield_nameer.cWhere. 
        
        DO ii = 1 TO NUM-ENTRIES(ttExternefield_nameer.cKeyfield_nameer, ';'):
            cKeyfield_name = ENTRY(ii, ttExternefield_nameer.cKeyfield_nameer, ';').
            hfield_name = iphttBrowser:BUFFER-FIELD(cKeyfield_name) NO-ERROR.
            CASE hfield_name:DATA-TYPE:
                WHEN 'INTEGER' OR
                WHEN 'INT64'   THEN 
                    cKeyValue = TRIM(STRING(INTEGER(hfield_name:BUFFER-VALUE(0)),'->>>>>>>>9')).
                WHEN 'DECIMAL' THEN 
                    cKeyValue = TRIM(STRING(DECIMAL(hfield_name:BUFFER-VALUE(0)),'->>>>>>>>9.99<<<')).
                WHEN 'DATE' THEN 
                    cKeyValue = STRING(DATE(hfield_name:BUFFER-VALUE(0)),'99.99.9999').
                OTHERWISE 
                cKeyValue = QUOTER(hfield_name:BUFFER-VALUE(0)).
            END CASE.
            cWhere = cWhere
                + (IF cWhere = '' THEN ' WHERE ' ELSE ' AND ')
                + SUBSTITUTE('&1.&2 = &3 ':U, ttExternefield_nameer.ctable, cKeyfield_name, cKeyValue).
        END.
        
        lRetVal = hBuffer:FIND-FIRST (cWhere) NO-ERROR.
        IF lRetVal THEN cfield_nameInhalt = hBuffer:BUFFER-FIELD(ipcfield_name):BUFFER-VALUE(0).

        RETURN cfield_nameInhalt.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC CHARACTER getHeader(
        INPUT httInput  AS HANDLE
        ):
        
        DEFINE VARIABLE cHeader AS CHARACTER NO-UNDO.

        FIND FIRST labeltexte NO-LOCK 
            WHERE labeltexte.company     = httInput::company
            AND   labeltexte.user_name   = httInput::user_name
            AND   labeltexte.program     = httInput::program
            AND   labeltexte.field_name  = 'KOPF'
            AND   labeltexte.language_id = INTEGER(httInput::language_id) NO-ERROR.
        IF NOT AVAILABLE labeltexte THEN 
        DO: 
            FIND FIRST labeltexte NO-LOCK 
                WHERE labeltexte.company     = httInput::company
                AND   labeltexte.program     = httInput::program
                AND   labeltexte.field_name  = 'KOPF'
                AND   labeltexte.language_id = INTEGER(httInput::language_id) NO-ERROR.
        END.
        
        cHeader = (IF AVAILABLE labeltexte THEN labeltexte.sidelabel ELSE httInput::program).
        
        RETURN cHeader.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC LOGICAL getHeaderData(
        INPUT  poRequest     AS IHttpRequest,
        OUTPUT cCompany      AS CHARACTER,
        OUTPUT cuser_name    AS CHARACTER,
        OUTPUT cAnzeigeName  AS CHARACTER,
        OUTPUT iLanguage_id  AS INTEGER ,
        OUTPUT cSessionToken AS CHARACTER
        ):
        
        DEFINE VARIABLE oHeader AS OpenEdge.Net.HTTP.HttpHeader NO-UNDO.
        DEFINE VARIABLE lRetVal AS LOGICAL                      NO-UNDO.

        oHeader      = poRequest:GetHeader('X-COMPANY').
        ccompany     = oHeader:VALUE.
        
        oHeader      = poRequest:GetHeader('X-USER-NAME').
        cuser_name    = oHeader:VALUE.
        
        oHeader      = poRequest:GetHeader('X-DISPLAY-NAME').
        cAnzeigeName = oHeader:VALUE.
        
        oHeader = poRequest:GetHeader('X-LANGUAGE-ID').
        ilanguage_id  = INTEGER(oHeader:VALUE).
        
        oHeader = poRequest:GetHeader('X-SESSION-TOKEN').
        cSessionToken = oHeader:VALUE.
        
        lRetVal = TRUE.
        RETURN lRetVal.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC LOGICAL getKeyFields(
        INPUT  oJsonIdent AS JsonObject,
        OUTPUT cKeyFields AS CHARACTER ,
        OUTPUT cKeyValues AS CHARACTER 
        ):
        
        DEFINE VARIABLE lRetVal     AS LOGICAL   NO-UNDO.
        
        DEFINE VARIABLE cFieldNames AS CHARACTER NO-UNDO EXTENT.
        DEFINE VARIABLE cFieldName  AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cString     AS CHARACTER NO-UNDO.
        DEFINE VARIABLE lOK         AS LOGICAL   NO-UNDO.
        DEFINE VARIABLE cValue      AS CHARACTER NO-UNDO.
        
        cKeyFields  = ''.
        cKeyValues  = ''.
        cFieldNames = oJsonIdent:getNames().
        DO i1 = 1 TO EXTENT(cFieldNames):
            IF NOT cFieldNames[i1] BEGINS 'keyfield' THEN NEXT.
            cKeyFields = cKeyFields
                + (IF cKeyFields = '' THEN '' ELSE ';')
                + REPLACE(cFieldNames[i1], 'keyfield_', '').
            cValue = oJsonIdent:GetCharacter(cFieldNames[i1]).
            cKeyValues = cKeyValues
                + (IF cKeyValues = '' THEN '' ELSE CHR(01))
                + cValue. 
        END.
        lOK = TRUE.
        DO i1 = 1 TO NUM-ENTRIES(cKeyFields, ';'):
            cString    = ENTRY(i1, cKeyFields, ';').
            cString    = ENTRY(1, cString, '_') + '_'.
            cFieldName = REPLACE(ENTRY(i1, cKeyFields, ';'), cString, '').
            
            DO WHILE lOK:
                FIND FIRST Ge_MIS._Field NO-LOCK 
                    WHERE Ge_MIS._Field._Field-Name = cFieldname NO-ERROR.
                IF NOT AVAILABLE Ge_MIS._Field THEN 
                DO:
                    lOK = FALSE.
                    LEAVE.
                END.
                
                CASE Ge_MIS._Field._Data-Type:
                    WHEN 'character' THEN 
                        ENTRY(i1, cKeyValues, CHR(01)) = QUOTER(ENTRY(i1, cKeyValues, CHR(01))).
                    WHEN 'logical'   THEN 
                        ENTRY(i1, cKeyValues, CHR(01)) = STRING(ENTRY(i1, cKeyValues, CHR(01)),"TRUE/FALSE").
                END CASE.
            
                LEAVE.
            END.
            
            DO WHILE NOT lOK:
                FIND FIRST FRAMEWORK._Field NO-LOCK 
                    WHERE FRAMEWORK._Field._Field-Name = cFieldname NO-ERROR.
                IF NOT AVAILABLE FRAMEWORK._Field THEN 
                DO:
                    lOK = FALSE.
                    LEAVE.
                END.
                
                CASE FRAMEWORK._Field._Data-Type:
                    WHEN 'character' THEN 
                        ENTRY(i1, cKeyValues, CHR(01)) = QUOTER(ENTRY(i1, cKeyValues, CHR(01))).
                    WHEN 'logical'   THEN 
                        ENTRY(i1, cKeyValues, CHR(01)) = STRING(ENTRY(i1, cKeyValues, CHR(01)),"TRUE/FALSE").
                END CASE.
            
                LEAVE.
            END.
        END.

        lRetVal = TRUE.
        RETURN lRetVal.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC CHARACTER getLabel(
        INPUT iprRecid  AS RECID,
        INPUT ipcArt    AS CHARACTER,
        INPUT ipilanguage_id  AS INTEGER 
        ):
        
        DEFINE VARIABLE cLabel AS CHARACTER NO-UNDO.
    
        DEFINE BUFFER bviewer_ze FOR viewer_ze.
    
        FIND bviewer_ze NO-LOCK WHERE RECID(bviewer_ze) = iprRecid.
    
        IF  ipilanguage_id = 0  OR
            ipilanguage_id > 10 THEN ipilanguage_id = 1.
    
        FIND FIRST labeltexte NO-LOCK 
            WHERE labeltexte.company     = bviewer_ze.company
            AND   labeltexte.user_name   = bviewer_ze.user_name
            AND   labeltexte.program     = bviewer_ze.program
            AND   labeltexte.table_name  = bviewer_ze.table_name
            AND   labeltexte.field_name  = bviewer_ze.field_name
            AND   labeltexte.language_id = ipilanguage_id NO-ERROR.
        IF NOT AVAILABLE labeltexte THEN 
        DO: 
            FIND FIRST labeltexte NO-LOCK 
                WHERE labeltexte.company     = bviewer_ze.company
                AND   labeltexte.program     = bviewer_ze.program
                AND   labeltexte.table_name  = bviewer_ze.table_name
                AND   labeltexte.field_name  = bviewer_ze.field_name
                AND   labeltexte.language_id = ipilanguage_id NO-ERROR.
        END.
        IF NOT AVAILABLE labeltexte THEN 
        DO:
            FIND FIRST labeltexte NO-LOCK 
                WHERE labeltexte.company     = bviewer_ze.company
                AND   labeltexte.table_name  = bviewer_ze.table_name
                AND   labeltexte.field_name  = bviewer_ze.field_name
                AND   labeltexte.language_id = ipilanguage_id NO-ERROR.
        END.
        IF NOT AVAILABLE labeltexte THEN 
        DO:
            FIND FIRST labeltexte NO-LOCK 
                WHERE labeltexte.company     = bviewer_ze.company
                AND   labeltexte.field_name  = bviewer_ze.field_name
                AND   labeltexte.language_id = ipilanguage_id NO-ERROR.
        END.

        CASE ipcArt:
            WHEN 'side' THEN 
                cLabel = (IF AVAILABLE labeltexte THEN labeltexte.sidelabel ELSE bviewer_ze.field_name).
            WHEN 'head' THEN 
                cLabel = (IF AVAILABLE labeltexte THEN labeltexte.headlabel ELSE bviewer_ze.field_name).
        END CASE.
    
        RETURN cLabel.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC CHARACTER getProgramName(
        INPUT oJsonIdent AS JsonObject,
        INPUT cUsers     AS CHARACTER 
        ):
        
        DEFINE VARIABLE cProgram     AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cCompany     AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cProgramUser AS CHARACTER NO-UNDO.

        cProgram = ''.
        cCompany = (IF oJsonIdent:HAS('company') THEN oJsonIdent:GetCharacter('company') ELSE oJsonIdent:GetCharacter('H_company')).
        DO i1 = 1 TO NUM-ENTRIES(cUsers, ','): 
            cProgramUser = ENTRY(i1, cUsers).
            FIND FIRST htmldokumente NO-LOCK 
                WHERE htmldokumente.company     = cCompany
                AND   htmldokumente.user_name   = cProgramUser
                AND   htmldokumente.form_id     = oJsonIdent:GetCharacter('formId' ) NO-ERROR.
            IF NOT AVAILABLE htmldokumente THEN NEXT. 

            cProgram = htmldokumente.program.
            LEAVE.
        END.
        
        RETURN cProgram.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC VOID readLastcWhere(
        INPUT  oJsonIdent  AS JsonObject,
        INPUT  cFileName   AS CHARACTER ,
        OUTPUT cWhere      AS CHARACTER 
        ):
        
        FIND userdata
            WHERE userdata.user_name   = oJsonIdent:GetCharacter('user_name')
            AND   userdata.company     = oJsonIdent:GetCharacter('company')
            AND   userdata.branch      = '0000'
            AND   userdata.record_type = 'where'
            AND   userdata.section     = cFileName 
            AND   userdata.key_type    = 'last' NO-ERROR.
              
        IF AVAILABLE userdata THEN cWhere = userdata.cfield_1. 
        RELEASE userdata.

        RETURN.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC VOID readSortFields(
        INPUT  oJsonIdent  AS JsonObject,
        INPUT  cFileName   AS CHARACTER ,
        OUTPUT cSortField  AS CHARACTER ,
        OUTPUT cDirection  AS CHARACTER 
        ):
            
        cSortField = ''.
        cDirection = ''.
        FIND userdata NO-LOCK
            WHERE userdata.user_name   = oJsonIdent:GetCharacter('user_name')
            AND   userdata.company     = oJsonIdent:GetCharacter('company')
            AND   userdata.branch      = '0000'
            AND   userdata.record_type = 'sortField'
            AND   userdata.section     = cFileName 
            AND   userdata.key_type    = '' NO-ERROR.
        IF AVAILABLE userdata THEN 
            ASSIGN
                cSortField = userdata.cfield_1
                cDirection = (IF userdata.cfield_2 BEGINS 'asc' THEN '' ELSE userdata.cfield_2).
        
        RETURN.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC HANDLE getWebMenuStructure(
        INPUT ipccompany      AS CHARACTER ,
        INPUT ipcuser_name    AS CHARACTER ,
        INPUT ipilanguage_id  AS INTEGER 
        ):
        
        DEFINE VARIABLE cuser_name AS CHARACTER NO-UNDO.
        DEFINE VARIABLE lAdmin     AS LOGICAL   NO-UNDO INIT FALSE.
        DEFINE VARIABLE htwebmenu  AS HANDLE    NO-UNDO.
        
        EMPTY TEMP-TABLE twebmenu.
        htwebmenu = TEMP-TABLE twebmenu:DEFAULT-BUFFER-HANDLE.
        
        cuser_name = ipcuser_name.
        lAdmin     = FALSE.
        DO WHILE TRUE.
            FIND FIRST webmenu NO-LOCK
                WHERE webmenu.company   = ipccompany
                AND   webmenu.user_name = ipcuser_name NO-ERROR.
            IF AVAILABLE webmenu    THEN LEAVE.
            IF cuser_name = 'Admin' THEN LEAVE.
            
            cuser_name = 'Admin'.
        END.
        
        FIND FIRST users NO-LOCK 
            WHERE users.user_name = cuser_name NO-ERROR.
        IF NOT AVAILABLE users THEN RETURN htwebmenu.

        lAdmin = users.lAdmin.         
        FOR EACH webmenu NO-LOCK
            WHERE webmenu.company   = ipccompany
            AND   webmenu.user_name = cuser_name :
                
            IF  NOT lAdmin              AND
                webmenu.menu_link <> '' AND
                webmenu.ladmin          THEN NEXT.
                
            CREATE  twebmenu.
            BUFFER-COPY webmenu
                EXCEPT  webmenu.created_at webmenu.updated_at
                TO      twebmenu.
        END.

        RETURN htwebmenu.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC CHARACTER getPrimaryIndexFields(
        INPUT ipctable AS CHARACTER
        ):
        
        DEFINE VARIABLE cFields    AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cDBNames   AS CHARACTER NO-UNDO INIT 'Ge_MIS;FRAMEWORK'.
        DEFINE VARIABLE cDBName    AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cFileName  AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cFieldName AS CHARACTER NO-UNDO.
        DEFINE VARIABLE ix         AS INTEGER   NO-UNDO.
        
        DO ix = 1 TO NUM-ENTRIES(cDBNames, ';'):
            cDBName   = ENTRY(ix, cDBNames, ';').
            cFileName = SUBSTITUTE('&1.&2', cDBName, ipcTable).
            CREATE BUFFER hBuffer FOR TABLE cFileName NO-ERROR.
            IF  NOT ERROR-STATUS:ERROR    AND
                VALID-HANDLE(hBuffer)     THEN LEAVE. 

            DELETE OBJECT hBuffer NO-ERROR.
            cDBName = ''.
        END.
        DELETE OBJECT hBuffer NO-ERROR.

        cFields = ''.               
        CASE cDBName:
            WHEN 'Ge_MIS' THEN 
                DO:
                    FIND FIRST Ge_MIS._File NO-LOCK 
                        WHERE Ge_MIS._File._File-Name = ipctable NO-ERROR.
                    // FIND FIRST Ge_MIS._Index NO-LOCK 
                    //     WHERE RECID(Ge_MIS._Index) = Ge_MIS._File._Prime-Index NO-ERROR.
                    FOR EACH Ge_MIS._Index-Field NO-LOCK 
                        WHERE Ge_MIS._Index-Field._Index-Recid = Ge_MIS._File._Prime-Index,
                        
                        FIRST Ge_MIS._Field NO-LOCK
                        WHERE RECID(Ge_MIS._Field) = Ge_MIS._index-Field._Field-recid
                        
                        BY Ge_MIS._Index-Field._Index-Seq:
                            
                        cFields = cFields 
                            + (IF cFields = '' THEN '' ELSE ';')
                            + Ge_MIS._Field._Field-Name.
                    END. 
                END.
            WHEN 'FRAMEWORK' THEN 
                DO:
                    FIND FIRST FRAMEWORK._File NO-LOCK 
                        WHERE FRAMEWORK._File._File-Name = ipctable NO-ERROR.
                    // FIND FIRST FRAMEWORK._Index NO-LOCK 
                    //     WHERE RECID(FRAMEWORK._Index) = FRAMEWORK._File._Prime-Index NO-ERROR.
                    FOR EACH FRAMEWORK._Index-Field NO-LOCK 
                        WHERE FRAMEWORK._Index-Field._Index-Recid = FRAMEWORK._File._Prime-Index,
                        
                        FIRST FRAMEWORK._Field NO-LOCK
                        WHERE RECID(FRAMEWORK._Field) = FRAMEWORK._index-Field._Field-recid
                        
                        BY FRAMEWORK._Index-Field._Index-Seq:
                            
                        cFields = cFields 
                            + (IF cFields = '' THEN '' ELSE ';')
                            + FRAMEWORK._Field._Field-Name.
                    END. 
                END.
        END CASE.

        RETURN cFields.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC CHARACTER getSysUser(  ):
        /*------------------------------------------------------------------------------
          Purpose:  
            Notes:  
        ------------------------------------------------------------------------------*/

        DEFINE VARIABLE mBen  AS MEMPTR    NO-UNDO.
        DEFINE VARIABLE iLeng AS INTEGER   INIT 100 NO-UNDO.
        DEFINE VARIABLE fok   AS INTEGER   NO-UNDO.
        DEFINE VARIABLE cBen  AS CHARACTER NO-UNDO.

        SET-SIZE(mBen) = iLeng.
        RUN GetUserNameA( OUTPUT mBen, INPUT-OUTPUT iLeng, OUTPUT fok ) NO-ERROR.
        ASSIGN 
            cBen = GET-STRING(mBen,1) NO-ERROR.

        SET-SIZE(mBen) = 0.

        RETURN cBen.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC CHARACTER getTitle(
        INPUT httInput  AS HANDLE
        ):
            
        DEFINE VARIABLE cTitel AS CHARACTER NO-UNDO.
        
        FIND FIRST labeltexte NO-LOCK 
            WHERE labeltexte.company     = httInput::company
            AND   labeltexte.user_name   = httInput::user_name
            AND   labeltexte.program     = httInput::program
            AND   labeltexte.field_name  = 'TITLE'
            AND   labeltexte.language_id = INTEGER(httInput::language_id) NO-ERROR.
        IF NOT AVAILABLE labeltexte THEN 
        DO: 
            FIND FIRST labeltexte NO-LOCK 
                WHERE labeltexte.company     = httInput::company
                AND   labeltexte.program     = httInput::program
                AND   labeltexte.field_name  = 'TITLE'
                AND   labeltexte.language_id = INTEGER(httInput::language_id) NO-ERROR.
        END.
        
        cTitel = (IF AVAILABLE labeltexte THEN labeltexte.sidelabel ELSE cProgramm).
        
        RETURN cTitel.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC LOGICAL readInputDatenFromJson(
        INPUT oJsonObject       AS JsonObject,
        INPUT hbttInput         AS HANDLE,
        INPUT-OUTPUT hbttTemp   AS HANDLE
        ):
        
        DEFINE VARIABLE lcJsonString AS LONGCHAR   NO-UNDO.
        DEFINE VARIABLE lcOriginal   AS LONGCHAR   NO-UNDO.
        
        DEFINE VARIABLE ctable       AS CHARACTER  NO-UNDO.
        
        DEFINE VARIABLE jsonttTemp   AS jsonObject NO-UNDO.
        
        DEFINE VARIABLE lRetVal      AS LOGICAL    NO-UNDO INIT FALSE.
        DEFINE VARIABLE cString      AS CHARACTER  NO-UNDO.
        
        jsonttTemp = NEW JsonObject().
        jsonttTemp = oJsonObject:GetJsonObject('ttTemp').
        lRetVal    = hbttTemp:READ-JSON ('JsonObject', jsonttTemp).
        hbttTemp:FIND-FIRST ().
        
        hbttTemp:WRITE-JSON('longchar', lcJsonString, FALSE).
        MESSAGE 'Daten zweiter Buffer -> ' STRING(lcJsonString). 

        lRetVal = TRUE.
        RETURN lRetVal.
        
    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC VOID readPosition(
        INPUT  oJsonIdent       AS JsonObject ,
        INPUT  cFileName        AS CHARACTER  ,
        OUTPUT iCurrentPosition AS INTEGER  
        ):
            
        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:  
            FIND userdata
                WHERE userdata.user_name   = oJsonIdent:GetCharacter('user_name')
                AND   userdata.company     = oJsonIdent:GetCharacter('company')
                AND   userdata.branch      = '0000'
                AND   userdata.record_type = 'position'
                AND   userdata.section     = cFileName 
                AND   userdata.key_type    = '' NO-ERROR.
              
            iCurrentPosition = (IF NOT AVAILABLE userdata THEN 1 ELSE userdata.ifield_1).
            RELEASE userdata.
            LEAVE.
        END.
        
        RETURN.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC VOID readStartcWhere(
        INPUT  oJsonIdent  AS JsonObject,
        INPUT  cFileName   AS CHARACTER ,
        OUTPUT cWhere      AS CHARACTER 
        ):
        
        FIND userdata
            WHERE userdata.user_name   = oJsonIdent:GetCharacter('user_name')
            AND   userdata.company     = oJsonIdent:GetCharacter('company')
            AND   userdata.branch      = '0000'
            AND   userdata.record_type = 'where'
            AND   userdata.section     = cFileName 
            AND   userdata.key_type    = 'start' NO-ERROR.
              
        IF AVAILABLE userdata THEN cWhere = userdata.cfield_1. 
        RELEASE userdata.

        RETURN.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC VOID setActiveSelection(
        INPUT  oJsonIdent       AS JsonObject,
        INPUT  cFileName        AS CHARACTER ,
        INPUT  cActiveSelection AS CHARACTER 
        ):
         
        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
            FIND userdata 
                WHERE userdata.user_name   = oJsonIdent:GetCharacter('user_name')
                AND   userdata.company     = oJsonIdent:GetCharacter('company')
                AND   userdata.branch      = '0000'
                AND   userdata.record_type = 'active'
                AND   userdata.section     = cFileName 
                AND   userdata.key_type    = '' NO-ERROR.
            IF NOT AVAILABLE UserData THEN 
            DO:
                CREATE userdata.
                ASSIGN
                    userdata.user_name   = oJsonIdent:GetCharacter('user_name')
                    userdata.company     = oJsonIdent:GetCharacter('company')
                    userdata.branch      = '0000'
                    userdata.record_type = 'active'
                    userdata.section     = cFileName 
                    userdata.key_type    = '' NO-ERROR.
            END.
            userdata.cfield_1 = cActiveSelection.
            RELEASE userdata.
            LEAVE.
        END.   

        RETURN.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC VOID setSortField(
        INPUT  cSortField          AS CHARACTER,
        INPUT-OUTPUT httBrowserKo AS HANDLE
        ):
        
        DO WHILE TRUE:
            IF httBrowserKo::sortfield = '' THEN
            DO:
                httBrowserKo::sortfield = cSortField + ':ASCENDING'.
                LEAVE.
            END.

            /*  ASCENDING / DESCENDING Kehren   */
            IF LOOKUP(cSortField, httBrowserKo::sortfield, ':') > 0 THEN
            DO:
                IF ENTRY(2, httBrowserKo::sortfield, ':') = 'ASCENDING' THEN
                DO:
                    ENTRY(2, httBrowserKo::sortfield, ':') = 'DESCENDING'.
                    LEAVE.
                END.
                ELSE
                DO:
                    ENTRY(2, httBrowserKo::sortfield, ':') = 'ASCENDING'.
                    LEAVE.
                END.
            END.

            httBrowserKo::sortfield = cSortField + ':ASCENDING'.

            LEAVE.
        END.
        
        updateBrowserKo( INPUT httBrowserKo ).
        
        RETURN.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC LOGICAL startBrowserKopf (
        INPUT  httInput     AS HANDLE,
        OUTPUT httBrowserKo AS HANDLE
        ):
            
        DEFINE VARIABLE rRecid AS RECID NO-UNDO.
        
        DEFINE BUFFER bbrowser_ko FOR browser_ko.
        
        FIND FIRST browser_ko NO-LOCK
            WHERE browser_ko.company    = httInput::company
            AND   browser_ko.user_name  = httInput::user_name
            AND   browser_ko.program    = httInput::program
            AND   browser_ko.table_name = httInput::table_name NO-ERROR.
        IF NOT AVAILABLE browser_ko THEN 
        DO:
            FIND FIRST browser_ko NO-LOCK
                WHERE browser_ko.company    = httInput::company
                AND   browser_ko.user_name  = 'admin'
                AND   browser_ko.program    = httInput::program
                AND   browser_ko.table_name = httInput::table_name NO-ERROR.
        END.
        IF NOT AVAILABLE browser_ko THEN RETURN FALSE.
        
        rRecid = RECID(browser_ko).
        
        REPEAT TRANSACTION:
            FIND browser_ko WHERE RECID(browser_ko) = rRecid.
            
            IF browser_ko.user_name = 'admin' THEN 
            DO:
                CREATE  bbrowser_ko.
                BUFFER-COPY browser_ko
                    EXCEPT  browser_ko.user_name
                    TO      bbrowser_ko
                    ASSIGN  
                    bbrowser_ko.user_name = httInput::user_name.
                rRecid = RECID(bbrowser_ko).
                FIND browser_ko WHERE RECID(browser_ko) = rRecid.
            END.
            
            ASSIGN
                browser_ko.actualpage = 0
                browser_ko.lastrecid  = 0.
            RELEASE browser_ko.
            LEAVE.
        END.
        
        FIND browser_ko NO-LOCK WHERE RECID(browser_ko) = rRecid.
        
        httBrowserKo = TEMP-TABLE ttBrowserKo:DEFAULT-BUFFER-HANDLE.
        httBrowserKo:EMPTY-TEMP-TABLE ().
        httBrowserKo:BUFFER-CREATE ().
        httBrowserKo:BUFFER-COPY(BUFFER browser_ko:HANDLE).
        
        RELEASE browser_ko.
        
        RETURN TRUE.
        
    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC LOGICAL startViewerKopf( 
        INPUT  httInput     AS HANDLE,
        OUTPUT httViewerKo AS HANDLE
        ):
            
        DEFINE VARIABLE rRecid AS RECID NO-UNDO.
        
        DEFINE BUFFER bviewer_ko FOR viewer_ko.
        
        FIND FIRST viewer_ko NO-LOCK
            WHERE viewer_ko.company    = httInput::company
            AND   viewer_ko.user_name  = httInput::user_name
            AND   viewer_ko.program    = httInput::program
            AND   viewer_ko.table_name = httInput::table_name NO-ERROR.
        IF NOT AVAILABLE viewer_ko THEN 
        DO:
            FIND FIRST viewer_ko NO-LOCK
                WHERE viewer_ko.company    = httInput::company
                AND   viewer_ko.user_name  = 'admin'
                AND   viewer_ko.program    = httInput::program
                AND   viewer_ko.table_name = httInput::table_name NO-ERROR.
        END.
        
        IF NOT AVAILABLE viewer_ko THEN RETURN FALSE.
        
        rRecid = RECID(viewer_ko).
        
        REPEAT TRANSACTION:
            FIND viewer_ko WHERE RECID(viewer_ko) = rRecid.
            
            IF viewer_ko.user_name = 'admin' THEN 
            DO:
                CREATE  bviewer_ko.
                BUFFER-COPY viewer_ko
                    EXCEPT  viewer_ko.user_name
                    TO      bviewer_ko
                    ASSIGN  
                    bviewer_ko.user_name = httInput::user_name.
                rRecid = RECID(bviewer_ko).
                FIND viewer_ko WHERE RECID(viewer_ko) = rRecid.
            END.
            
            RELEASE viewer_ko.
            LEAVE.
        END.
        
        FIND viewer_ko WHERE RECID(viewer_ko) = rRecid.
        
        httviewerKo = TEMP-TABLE ttviewerKo:DEFAULT-BUFFER-HANDLE.
        httviewerKo:EMPTY-TEMP-TABLE ().
        httviewerKo:BUFFER-CREATE ().
        httviewerKo:BUFFER-COPY(BUFFER viewer_ko:HANDLE).
        
        RELEASE viewer_ko.
        
        RETURN TRUE.
        
    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC LONGCHAR trimStructure(
        INPUT oJsonInput AS JsonObject
        ):

        DEFINE VARIABLE lcResult AS LONGCHAR NO-UNDO.
        DEFINE VARIABLE ii       AS INTEGER  NO-UNDO.
        
        lcResult = TRIM(oJsonInput:GetJsonText()).
        lcResult = SUBSTRING(lcResult,02).
        ii = LENGTH(lcResult) - 1.
        lcResult = SUBSTRING(lcResult,01, ii).
        
        RETURN lcResult.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC VOID updateBrowserKo(
        INPUT httBrowserKo AS HANDLE
        ):
        
        DEFINE VARIABLE hBrowserKo AS HANDLE NO-UNDO.
        
        hBrowserKo = BUFFER browser_ko:HANDLE.
        
        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
            
            FIND browser_ko EXCLUSIVE-LOCK 
                WHERE browser_ko.company    = httBrowserKo::company
                AND   browser_ko.user_name  = httBrowserKo::user_name
                AND   browser_ko.program    = httBrowserKo::program
                AND   browser_ko.table_name = httBrowserKo::table_name NO-ERROR.
            IF NOT AVAILABLE browser_ko THEN LEAVE.
            
            DO i1 = 1 TO httBrowserKo:NUM-FIELDS:
                IF httBrowserKo:BUFFER-FIELD(i1):BUFFER-VALUE(0) = hBrowserKo:BUFFER-FIELD(i1):BUFFER-VALUE(0) THEN NEXT.
                hBrowserKo:BUFFER-FIELD(i1):BUFFER-VALUE(0) = httBrowserKo:BUFFER-FIELD(i1):BUFFER-VALUE(0).
            END.
            
            RELEASE browser_ko.
            LEAVE.
        END.
        
        RETURN.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC VOID writeLastcWhere(
        INPUT  oJsonIdent  AS JsonObject,
        INPUT  cFileName   AS CHARACTER ,
        INPUT  cWhere      AS CHARACTER 
        ):
        
        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:  
            FIND userdata
                WHERE userdata.user_name   = oJsonIdent:GetCharacter('user_name')
                AND   userdata.company     = oJsonIdent:GetCharacter('company')
                AND   userdata.branch      = '0000'
                AND   userdata.record_type = 'where'
                AND   userdata.section     = cFileName 
                AND   userdata.key_type    = 'last' NO-ERROR.
              
            IF NOT AVAILABLE userdata THEN 
            DO:
                CREATE  userdata.
                ASSIGN 
                    userdata.user_name   = oJsonIdent:GetCharacter('user_name')
                    userdata.company     = oJsonIdent:GetCharacter('company')
                    userdata.branch      = '0000'
                    userdata.record_type = 'where'
                    userdata.section     = cFileName 
                    userdata.key_type    = 'last' NO-ERROR.
            END.
            ASSIGN  
                userdata.cfield_1 = cWhere.
            RELEASE userdata.
            LEAVE.
        END.

        RETURN.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC VOID writePosition(
        INPUT  oJsonIdent       AS JsonObject ,
        INPUT  cFileName        AS CHARACTER  ,
        INPUT  iCurrentPosition AS INTEGER  
        ):
            
        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:  
            FIND userdata
                WHERE userdata.user_name   = oJsonIdent:GetCharacter('user_name')
                AND   userdata.company     = oJsonIdent:GetCharacter('company')
                AND   userdata.branch      = '0000'
                AND   userdata.record_type = 'position'
                AND   userdata.section     = cFileName 
                AND   userdata.key_type    = '' NO-ERROR.
              
            IF NOT AVAILABLE userdata THEN 
            DO:
                CREATE  userdata.
                ASSIGN 
                    userdata.user_name   = oJsonIdent:GetCharacter('user_name')
                    userdata.company     = oJsonIdent:GetCharacter('company')
                    userdata.branch      = '0000'
                    userdata.record_type = 'position'
                    userdata.section     = cFileName 
                    userdata.key_type    = '' NO-ERROR.
            END.
            ASSIGN  
                userdata.ifield_1 = iCurrentPosition.
            RELEASE userdata.
            LEAVE.
        END.
        
        RETURN.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC VOID writeSortfields(
        INPUT  oJsonIdent  AS JsonObject,
        INPUT  cFileName   AS CHARACTER ,
        INPUT  cSortField  AS CHARACTER ,
        INPUT  cDirection  AS CHARACTER 
        ):
        
        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:  
            FIND userdata
                WHERE userdata.user_name   = oJsonIdent:GetCharacter('user_name')
                AND   userdata.company     = oJsonIdent:GetCharacter('company')
                AND   userdata.branch      = '0000'
                AND   userdata.record_type = 'sortField'
                AND   userdata.section     = cFileName 
                AND   userdata.key_type    = '' NO-ERROR.
              
            IF NOT AVAILABLE userdata THEN 
            DO:
                CREATE  userdata.
                ASSIGN 
                    userdata.user_name   = oJsonIdent:GetCharacter('user_name')
                    userdata.company     = oJsonIdent:GetCharacter('company')
                    userdata.branch      = '0000'
                    userdata.record_type = 'sortField'
                    userdata.section     = cFileName 
                    userdata.key_type    = '' NO-ERROR.
            END.
            ASSIGN  
                userdata.cfield_1 = cSortfield
                userdata.cfield_2 = cDirection.
            RELEASE userdata.
            LEAVE.
        END.

        RETURN.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC VOID writeStartcWhere(
        INPUT  oJsonIdent  AS JsonObject,
        INPUT  cFileName   AS CHARACTER ,
        INPUT  cWhere      AS CHARACTER 
        ):
        
        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:  
            FIND userdata
                WHERE userdata.user_name   = oJsonIdent:GetCharacter('user_name')
                AND   userdata.company     = oJsonIdent:GetCharacter('company')
                AND   userdata.branch      = '0000'
                AND   userdata.record_type = 'where'
                AND   userdata.section     = cFileName 
                AND   userdata.key_type    = 'start' NO-ERROR.
              
            IF NOT AVAILABLE userdata THEN 
            DO:
                CREATE  userdata.
                ASSIGN 
                    userdata.user_name   = oJsonIdent:GetCharacter('user_name')
                    userdata.company     = oJsonIdent:GetCharacter('company')
                    userdata.branch      = '0000'
                    userdata.record_type = 'where'
                    userdata.section     = cFileName 
                    userdata.key_type    = 'start' NO-ERROR.
            END.
            ASSIGN  
                userdata.cfield_1 = cWhere.
            RELEASE userdata.
            LEAVE.
        END.

        RETURN.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/
    DESTRUCTOR PUBLIC utilitiesHandler ( ):
        MESSAGE 'Destructor utilitiesHandler '.
    /*        DELETE OBJECT hQuery NO-ERROR.    */
    /*        DELETE OBJECT hBuffer NO-ERROR.   */
    END DESTRUCTOR.

END CLASS.