 
/*------------------------------------------------------------------------
   File        : usersHandler
   Purpose     : 
   Syntax      : 
   Description : 
   Author(s)   : walter.riechsteiner
   Created     : Fri Nov 21 11:31:01 CET 2025
   Notes       : 
 ----------------------------------------------------------------------*/


BLOCK-LEVEL ON ERROR UNDO, THROW.

USING Progress.Json.ObjectModel.JsonObject FROM PROPATH.
USING Progress.Json.ObjectModel.JsonArray FROM PROPATH.
USING utilities.utilitiesHandler FROM PROPATH.
USING Progress.Json.ObjectModel.ObjectModelParser FROM PROPATH.
USING OpenEdge.DataAdmin.IIndex FROM PROPATH.
USING OpenEdge.Web.DataObject.Writer.JsonObjectValueWriter FROM PROPATH.

CLASS admin.adminprogsHandler FINAL:
    DEFINE VARIABLE oJsonData         AS JsonObject        NO-UNDO.
    DEFINE VARIABLE oJsonArray        AS JsonArray         NO-UNDO.
    DEFINE VARIABLE oParser           AS ObjectModelParser NO-UNDO.
    
    DEFINE VARIABLE cuser_name        AS CHARACTER         NO-UNDO.
    DEFINE VARIABLE ccompany          AS CHARACTER         NO-UNDO.
    DEFINE VARIABLE lcJsonString      AS LONGCHAR          NO-UNDO.
    DEFINE VARIABLE iLanguage_id      AS INTEGER           NO-UNDO.

    DEFINE VARIABLE oRecords          AS JsonArray         NO-UNDO.
    DEFINE VARIABLE oJsonPosition     AS JsonObject        NO-UNDO.
        
    DEFINE VARIABLE cFileName         AS CHARACTER         NO-UNDO.
    DEFINE VARIABLE lCompany          AS LOGICAL           NO-UNDO.
    DEFINE VARIABLE lActive           AS LOGICAL           NO-UNDO.
    DEFINE VARIABLE lWordindex        AS LOGICAL           NO-UNDO.
    DEFINE VARIABLE iMaxRecords       AS INTEGER           NO-UNDO INIT 20.
    DEFINE VARIABLE iStartPage        AS INTEGER           NO-UNDO.
    DEFINE VARIABLE iStartRecord      AS INTEGER           NO-UNDO.
    DEFINE VARIABLE iPageCounter      AS INTEGER           NO-UNDO.
    DEFINE VARIABLE iCurrentPosition  AS INTEGER           NO-UNDO.
    DEFINE VARIABLE cFieldReplace     AS CHARACTER         NO-UNDO.
    DEFINE VARIABLE cKeyFieldReplace  AS CHARACTER         NO-UNDO.
    DEFINE VARIABLE cFilterReplace    AS CHARACTER         NO-UNDO.
    DEFINE VARIABLE cFileReplace      AS CHARACTER         NO-UNDO.
    DEFINE VARIABLE cKeyFields        AS CHARACTER         NO-UNDO.
    DEFINE VARIABLE cKeyValues        AS CHARACTER         NO-UNDO.
    DEFINE VARIABLE cWhere            AS CHARACTER         NO-UNDO.
    DEFINE VARIABLE cString           AS CHARACTER         NO-UNDO.
    DEFINE VARIABLE cMessage          AS CHARACTER         NO-UNDO.
    DEFINE VARIABLE lcMessage         AS LONGCHAR          NO-UNDO.
    
    DEFINE VARIABLE iActualPage       AS INTEGER           NO-UNDO.
    DEFINE VARIABLE cPrimaryKey       AS CHARACTER         NO-UNDO.
    DEFINE VARIABLE iIndex            AS INTEGER           NO-UNDO.
    DEFINE VARIABLE iStartIndex       AS INTEGER           NO-UNDO.
    
    DEFINE VARIABLE httTable          AS HANDLE            NO-UNDO.
    DEFINE VARIABLE ttTable           AS HANDLE            NO-UNDO.
    
    DEFINE VARIABLE hQuery            AS HANDLE            NO-UNDO.
    DEFINE VARIABLE hBuffer           AS HANDLE            NO-UNDO.
    
    DEFINE VARIABLE outilitiesHandler AS utilitiesHandler  NO-UNDO.
    
    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC LOGICAL createData(
        INPUT  oJsonIdent  AS JsonObject,
        INPUT  oJsonRecord AS jsonObject,
        OUTPUT oJsonReturn AS JsonObject  
        ):
            
        DEFINE VARIABLE oJsonMessage  AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonPosition AS JsonObject NO-UNDO.

        DEFINE VARIABLE lRetVal       AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE lOK           AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE ii            AS INTEGER    NO-UNDO.
        DEFINE VARIABLE i1            AS INTEGER    NO-UNDO.
        DEFINE VARIABLE iIndex        AS INTEGER    NO-UNDO.
        DEFINE VARIABLE cWordIndex    AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cSortField    AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cDirection    AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE hField        AS HANDLE     NO-UNDO.
        DEFINE VARIABLE htField       AS HANDLE     NO-UNDO.
        DEFINE VARIABLE cField        AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cValue        AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cIndexFields  AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE rBuffer       AS RECID      NO-UNDO.

        outilitiesHandler = NEW utilitiesHandler().

        outilitiesHandler:evaluateFile(
            INPUT  oJsonIdent   ,
            OUTPUT cFileName    ,
            OUTPUT lCompany     ,
            OUTPUT lActive      ,
            OUTPUT lWordindex
            ).
            
        cFieldReplace    = SUBSTITUTE('&1_', cFileName).
        cKeyFieldReplace = SUBSTITUTE('keyfield_&1_', cFileName).
        cFilterReplace   = SUBSTITUTE('filter_&1_', cFileName).
        cFileReplace     = SUBSTITUTE('&1_', cFileName).
        iLanguage_id     = oJsonIdent:GetInteger('language_id').

        lOK = outilitiesHandler:getKeyFields(
            INPUT  oJsonIdent   ,
            OUTPUT cKeyFields   ,
            OUTPUT cKeyValues
            ).

        CREATE TEMP-TABLE ttTable.
        ttTable:ADD-FIELDS-FROM (cFileName, 'wordindex'). /*  except Field wordindex  */
        ttTable:TEMP-TABLE-PREPARE ('record').
        httTable = ttTable:DEFAULT-BUFFER-HANDLE.

        DO ii = 1 TO httTable:NUM-FIELDS:
            httTable:BUFFER-FIELD(ii):SERIALIZE-NAME = cFileName + '_' + httTable:BUFFER-FIELD(ii):NAME NO-ERROR.
        END.

        httTable:READ-JSON('JsonObject', oJsonRecord) NO-ERROR.
        httTable:FIND-FIRST('', NO-LOCK).
        
        CREATE BUFFER hBuffer FOR TABLE cFileName.
        cIndexFields = outilitiesHandler:getPrimaryIndexFields(
            INPUT cFileName
            ).

        cWhere = ''.    
        DO i1 = 1 TO NUM-ENTRIES(cIndexFields, ';'):
            cField = ENTRY(i1, cIndexFields, ';').
            hField = httTable:BUFFER-FIELD(cField):HANDLE.
            CASE hField:DATA-TYPE:
                WHEN 'character' THEN 
                    cValue = QUOTER(hField:BUFFER-VALUE).
                WHEN 'logical'   THEN 
                    cValue = STRING(hField:BUFFER-VALUE,"TRUE/FALSE").
                WHEN 'date'      THEN 
                    cValue = STRING(DATE(hField:BUFFER-VALUE)).
                OTHERWISE             
                cValue = hField:BUFFER-VALUE. 
            END CASE.
            cWhere = cWhere
                + (IF cWhere = '' THEN 'WHERE ' ELSE ' AND ')
                + SUBSTITUTE('&1.&2 = ', cFileName, cField)
                + cValue.
        END.

        lRetVal = FALSE.
        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
            lOK = hBuffer:FIND-UNIQUE(cWhere) NO-ERROR. 
            IF hBuffer:AVAILABLE THEN 
            DO:
                outilitiesHandler:getErrorMessage(
                    INPUT  '1023',
                    INPUT  ilanguage_id,
                    INPUT  '',
                    OUTPUT lcMessage).
                LEAVE.
            END.

            hBuffer:BUFFER-CREATE ().
            DO ii = 1 TO httTable:NUM-FIELDS:
                hField  = hBuffer:BUFFER-FIELD(ii):HANDLE NO-ERROR.
                IF  ERROR-STATUS:ERROR       OR
                    NOT VALID-HANDLE(hField) THEN NEXT.
                    
                htField = httTable:BUFFER-FIELD(ii):HANDLE NO-ERROR.
                IF htField:BUFFER-VALUE = hField:BUFFER-VALUE THEN NEXT.
                hField:BUFFER-VALUE = htField:BUFFER-VALUE. 
            END.
            htField = httTable:BUFFER-FIELD('created_at'):HANDLE NO-ERROR.
            IF  NOT ERROR-STATUS:ERROR AND 
                VALID-HANDLE(htField)  THEN htField:BUFFER-VALUE = NOW.
            
            htField = httTable:BUFFER-FIELD('wordindex'):HANDLE NO-ERROR.
            IF  NOT ERROR-STATUS:ERROR AND 
                VALID-HANDLE(htField)  THEN 
            DO:
                cWordIndex = outilitiesHandler:createWordindex(
                    INPUT hBuffer
                    ).
                htField:BUFFER-VALUE = cWordIndex.
            END.
            rBuffer = hBuffer:RECID.
            hBuffer:BUFFER-RELEASE ().
            
            lRetVal = TRUE.
            LEAVE.
        END.
        
        DO WHILE TRUE:
            outilitiesHandler:readLastcWhere(
                INPUT  oJsonIdent,
                INPUT  cFileName ,
                OUTPUT cWhere
                ).
// MESSAGE 'readlastcwhere = ' cWhere.
            ASSIGN 
                ii               = 0
                i1               = 0
                iActualPage      = 0
                iCurrentPosition = 0.
        
            ttTable:EMPTY-TEMP-TABLE ().
            CREATE QUERY hQuery.
            hQuery:SET-BUFFERS   (hBuffer) NO-ERROR.
            hQuery:QUERY-PREPARE (cWhere)  NO-ERROR.
            hQuery:QUERY-OPEN ().
            hQuery:GET-FIRST  ().
// MESSAGE 'cPrimaryKey = ' cPrimaryKey '- cWhere = ' cWhere.
            lOK = FALSE.
            DO WHILE NOT hQuery:QUERY-OFF-END:
                ii = ii + 1.
                IF ii < iStartRecord THEN 
                DO:
                    hQuery:GET-NEXT ().
                    NEXT.
                END.
                IF  NOT lOK                AND
                    ii MOD iMaxRecords = 1 THEN iActualPage = iActualPage + 1.
                IF NOT lOK THEN 
                DO:
                    IF hBuffer:RECID <> rBuffer THEN 
                    DO:
                        hQuery:GET-NEXT().
                        NEXT.
                    END.
                    iIndex = ii MOD iMaxRecords.
                    iStartIndex = ii - iIndex + 1.
                    DO WHILE ii > iStartIndex:
                        hQuery:GET-PREV ().
                        ii = ii - 1.
                    END.
                    lOK = TRUE.
                END.
                IF iCurrentPosition = 0 THEN iCurrentPosition = ii.
                i1 = i1 + 1.
                hQuery:GET-NEXT ().
            END.
            hQuery:QUERY-CLOSE ().
            DELETE OBJECT hBuffer NO-ERROR.
        
            IF ii = 0 THEN RETURN FALSE.

            iPageCounter = ii / iMaxRecords.
            IF (iPageCounter * iMaxRecords) < ii THEN iPageCounter = iPageCounter + 1. 
 
            oJsonPosition = NEW JsonObject().
            oJsonPosition:ADD('page' , iActualPage).
            oJsonPosition:ADD('index', iIndex - 1).     /* -1 weil in Java beginnt Index bei 0  */
        
            oRecords = NEW JsonArray().
            httTable:WRITE-JSON('JsonArray', oRecords).
        
            oJsonReturn = NEW JsonObject().
            // oJsonReturn:ADD('records'   , oRecords).
            oJsonReturn:ADD('maxRecords', ii).
            oJsonReturn:ADD('pageCount' , iPageCounter).
            oJsonReturn:ADD('position'  , oJsonPosition).
            outilitiesHandler:writePosition(
                INPUT  oJsonIdent       ,
                INPUT  cFileName        ,
                INPUT  iCurrentPosition 
                ).
            
            lRetVal = TRUE.        
            RETURN lRetVal.
        END.

        IF NOT lRetVal THEN 
        DO:
            oJsonMessage = NEW JsonObject().
            oJsonMessage:ADD('success', FALSE).
            oJsonMessage:ADD('message', lcMessage).
            oJsonMessage:WRITE(lcJsonString, FALSE).
            
            oJsonReturn = oJsonMessage.
        END.
        
        RETURN lRetVal.

        CATCH e AS Progress.Lang.Error:

        END CATCH.

        FINALLY:

        END FINALLY.

    END METHOD.

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

    METHOD PUBLIC LOGICAL deleteData(
        INPUT  oJsonIdent  AS JsonObject,
        INPUT  oJsonRecord AS jsonObject,
        OUTPUT oJsonReturn AS JsonObject  
        ):

        DEFINE VARIABLE oJsonMessage  AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonPosition AS JsonObject NO-UNDO.

        DEFINE VARIABLE lRetVal       AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE lOK           AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE ii            AS INTEGER    NO-UNDO.
        DEFINE VARIABLE i1            AS INTEGER    NO-UNDO.
        DEFINE VARIABLE iIndex        AS INTEGER    NO-UNDO.
        DEFINE VARIABLE cWordIndex    AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cSortField    AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cDirection    AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE hField        AS HANDLE     NO-UNDO.
        DEFINE VARIABLE cField        AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cValue        AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cIndexFields  AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE rBuffer       AS ROWID      NO-UNDO.

        outilitiesHandler = NEW utilitiesHandler().

        outilitiesHandler:evaluateFile(
            INPUT  oJsonIdent   ,
            OUTPUT cFileName    ,
            OUTPUT lCompany     ,
            OUTPUT lActive      ,
            OUTPUT lWordindex
            ).
            
        cFieldReplace    = SUBSTITUTE('&1_', cFileName).
        cKeyFieldReplace = SUBSTITUTE('keyfield_&1_', cFileName).
        cFilterReplace   = SUBSTITUTE('filter_&1_', cFileName).
        cFileReplace     = SUBSTITUTE('&1_', cFileName).
        iLanguage_id     = oJsonIdent:GetInteger('language_id').
        ccompany         = oJsonIdent:GetCharacter('company').

        lOK = outilitiesHandler:getKeyFields(
            INPUT  oJsonIdent   ,
            OUTPUT cKeyFields   ,
            OUTPUT cKeyValues
            ).

        CREATE TEMP-TABLE ttTable.
        ttTable:ADD-FIELDS-FROM (cFileName, 'wordindex'). /*  except Field wordindex  */
        ttTable:TEMP-TABLE-PREPARE ('record').
        httTable = ttTable:DEFAULT-BUFFER-HANDLE.

        DO ii = 1 TO httTable:NUM-FIELDS:
            httTable:BUFFER-FIELD(ii):SERIALIZE-NAME = cFileName + '_' + httTable:BUFFER-FIELD(ii):NAME NO-ERROR.
        END.

        httTable:READ-JSON('JsonObject', oJsonRecord) NO-ERROR.
        httTable:FIND-FIRST('', NO-LOCK).

        //  Primary-Index-Fields fuer WHERE-Statement        
        CREATE BUFFER hBuffer FOR TABLE cFileName.
        cIndexFields = outilitiesHandler:getPrimaryIndexFields(
            INPUT cFileName
            ).

        //  Erzeugen von Where-Statement für UNIQUE-Find
        cWhere = ''.    
        DO i1 = 1 TO NUM-ENTRIES(cIndexFields, ';'):
            cField = ENTRY(i1, cIndexFields, ';').
            hField = httTable:BUFFER-FIELD(cField):HANDLE.
            CASE hField:DATA-TYPE:
                WHEN 'character' THEN 
                    cValue = QUOTER(hField:BUFFER-VALUE).
                WHEN 'logical'   THEN 
                    cValue = STRING(hField:BUFFER-VALUE,"TRUE/FALSE").
                WHEN 'date'      THEN 
                    cValue = STRING(DATE(hField:BUFFER-VALUE)).
                OTHERWISE             
                cValue = hField:BUFFER-VALUE. 
            END CASE.
            cWhere = cWhere
                + (IF cWhere = '' THEN 'WHERE ' ELSE ' AND ')
                + SUBSTITUTE('&1.&2 = ', cFileName, cField)
                + cValue.
        END.
                
        lRetVal = FALSE.
        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
            lOK = hBuffer:FIND-UNIQUE (cWhere, NO-LOCK ) NO-ERROR.
            IF NOT lOK THEN 
            DO:
                outilitiesHandler:getErrorMessage(
                    INPUT  '1014',
                    INPUT  ilanguage_id,
                    INPUT  '',
                    OUTPUT lcMessage).
                LEAVE.
            END.
            rBuffer = hBuffer:ROWID.

            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 AVAILABLE userdata THEN 
            DO: 
                ASSIGN 
                    cSortField = userdata.cfield_1
                    cDirection = userdata.cfield_2.
            END.
            IF cDirection BEGINS 'asc' THEN cDirection = ''.
                    
            //  Where-Statement f�r FOR EACH Filename f�r die Anzeige            
            cWhere  = ''.
            IF lCompany THEN cWhere = SUBSTITUTE('WHERE &1.company = &2', cFileName, QUOTER(ccompany)).
            IF cKeyFields <> '' THEN
            DO:
                DO ii = 1 TO NUM-ENTRIES(cKeyFields, ';'):
                    cField = ENTRY(ii, cKeyFields, ';').
                    cField = REPLACE(cField, cKeyFieldReplace, '').
                    cField = REPLACE(cField, cFilterReplace, '').
                    cField = REPLACE(cField, cFileReplace, '').
                    cValue = ENTRY(ii, cKeyValues, CHR(01)).
                    IF  lCompany           AND
                        cFIeld = 'company' THEN NEXT.                  
                    cValue = ENTRY(ii, cKeyValues, CHR(01)).
                    cWhere = cWhere
                        + (IF cWhere = '' THEN 'WHERE &1.&2 = &3' ELSE ' AND &1.&2 = &3').
                    cWhere = SUBSTITUTE(cWhere, cFileName, cField, cValue).
                END.
            END.

            CREATE QUERY hQuery.
            hQuery:SET-BUFFERS (hBuffer).
            cWhere = SUBSTITUTE('FOR EACH &1 NO-LOCK &2 ', cFileName, cWhere).
            IF cSortField <> '' THEN cWhere = cWhere + ' BY ' + cSortField + ' ' + cDirection.
            
            hQuery:QUERY-PREPARE(cWhere).
            hQuery:QUERY-OPEN().
            hQuery:GET-FIRST().
            
            ii = 0.
            i1 = 0.  
            DO WHILE NOT hQuery:QUERY-OFF-END:
                ii = ii + 1.
                IF hBuffer:ROWID = rBuffer THEN i1 = ii.
                hQuery:GET-NEXT ().
            END.
            hQuery:QUERY-CLOSE ().
        
            iPageCounter = i1 / iMaxRecords.
            IF (iPageCounter * iMaxRecords) < i1 THEN iPageCounter = iPageCounter + 1.

            iIndex = i1 MOD iMaxRecords.
            IF iIndex = 0 THEN iIndex = iMaxRecords.
            
            lOK = hBuffer:FIND-BY-ROWID (rBuffer, EXCLUSIVE-LOCK) NO-ERROR.
            hField = hBuffer:BUFFER-FIELD('active'):HANDLE NO-ERROR.
            IF  NOT ERROR-STATUS:ERROR AND
                VALID-HANDLE(hField) THEN 
            DO:
                hField:BUFFER-VALUE = FALSE.
                hField = hBuffer:BUFFER-FIELD('updated_at'):HANDLE NO-ERROR.
                IF  NOT ERROR-STATUS:ERROR AND 
                    VALID-HANDLE(hField)   THEN hField:BUFFER-VALUE = NOW.
            END.
            ELSE 
            DO:
                hBuffer:BUFFER-DELETE ().
            END.
            hBuffer:BUFFER-RELEASE ().
            
            lRetVal     = TRUE.
            oJsonReturn = NEW JsonObject().
            oJsonReturn:ADD('success', lRetVal).
            
            oJsonPosition = NEW JsonObject().
            oJsonPosition:ADD('page', iPageCounter).
            oJsonPosition:ADD('index', iIndex - 1).     /* -1 weil in Java beginnt Index bei 0  */
            oJsonPosition:ADD('totalRecords', ii).
            
            oJsonReturn:ADD('position', oJsonPosition).

            LEAVE.
        END.
                
        RETURN lRetVal.
        
        CATCH e AS Progress.Lang.Error:
        
        END CATCH.
        
        FINALLY:
        
        END FINALLY.

    END METHOD.

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

    METHOD PUBLIC LOGICAL getChanges(
        INPUT  oJsonIdent  AS JsonObject,
        OUTPUT oJsonResult AS JsonObject
        ):
    /*
              DEFINE VARIABLE lRetVal           AS LOGICAL    NO-UNDO.
                          
              DEFINE VARIABLE cFunction         AS CHARACTER  NO-UNDO.
              DEFINE VARIABLE cField            AS CHARACTER  NO-UNDO.
              DEFINE VARIABLE cAction           AS CHARACTER  NO-UNDO.
              DEFINE VARIABLE cValue            AS CHARACTER  NO-UNDO.
              DEFINE VARIABLE lcJsonString      AS LONGCHAR   NO-UNDO.
              DEFINE VARIABLE cWhere            AS CHARACTER  NO-UNDO.
                          
              DEFINE VARIABLE i1                AS INTEGER    NO-UNDO.
              DEFINE VARIABLE i2                AS INTEGER    NO-UNDO.
                          
              DEFINE VARIABLE oJsonfieldUpdates AS JsonObject NO-UNDO.
                          
              outilitiesHandler = NEW utilitiesHandler().
                          
              cField  = oJsonIdent:GetCharacter('field').
              cAction = oJsonIdent:GetCharacter('action').
              cValue  = REPLACE(oJsonIdent:GetCharacter('value'), '+', ' ').
                  
              oJsonResult       = NEW JsonObject().
              oJsonFieldUpdates = NEW JsonObject().
                  
              lRetVal = outilitiesHandler:getKeyFields(
                  INPUT  oJsonIdent   ,
                  OUTPUT cKeyFields   ,
                  OUTPUT cKeyValues
                  ).
              cWhere     = ''.
              lRetVal    = FALSE.
              DO WHILE TRUE:
                  DO i1 = 1 TO NUM-ENTRIES(cKeyFields, ';'):
                      cWhere = cWhere
                          + (IF cWhere = '' THEN 'WHERE ' ELSE 'AND ' )
                          + SUBSTITUTE('busers.&1 = &2 ',
                          REPLACE(ENTRY(i1, cKeyFields, ';'), 'users_', ''),
                          QUOTER (ENTRY(i1, cKeyValues, CHR(01)))).
                  END.
                  MESSAGE cWhere.
                  hBuffer = BUFFER busers:HANDLE.
                  lRetVal = hBuffer:FIND-UNIQUE(cWhere, NO-LOCK) NO-ERROR.
                  IF lRetVal THEN 
                  DO:
                      CASE cField:
                          WHEN 'users_firstname' THEN 
                              DO:
                                  IF hBuffer::display_Name = '' THEN 
                                  DO:
                                      cString = cValue + ' ' + hBuffer::lastname.
                                      oJsonfieldUpdates:ADD('users_display_name', cString).
                                  END.
                                  IF hBuffer::initials = '' THEN 
                                  DO:
                                      cString = TRIM(SUBSTRING(cValue,01,02)) + TRIM(SUBSTRING(hBuffer::lastname,01,02)).
                                      oJsonfieldUpdates:ADD('users_initials', cString).
                                  END.
                              END.
                      END CASE.
                      oJsonResult:ADD('fieldUpdates', oJsonfieldUpdates).
                  END.
                          
                  lRetVal = TRUE.
                  LEAVE.
              END.
                  
              IF NOT lRetVal THEN 
              DO:
                  oJsonResult = NEW JsonObject().
                  oJsonResult:ADD('success', FALSE).
                  oJsonResult:ADD('message', 'Fehler beim change').
              END.
                                  
              RETURN lRetVal.
    */
    END METHOD.

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

    METHOD PUBLIC LOGICAL getData(
        INPUT  oJsonIdent  AS JsonObject,
        OUTPUT oJsonReturn AS JsonObject  
        ):
        
        DEFINE VARIABLE ii           AS INTEGER   NO-UNDO.
        DEFINE VARIABLE i1           AS INTEGER   NO-UNDO.
        DEFINE VARIABLE iNumerisch   AS INTEGER   NO-UNDO.
        DEFINE VARIABLE lRetVal      AS LOGICAL   NO-UNDO.
        DEFINE VARIABLE cSortField   AS CHARACTER NO-UNDO INIT ''.
        DEFINE VARIABLE cSearchChars AS CHARACTER NO-UNDO INIT ''.
        DEFINE VARIABLE cValue       AS CHARACTER NO-UNDO.
        DEFINE VARIABLE lSearch      AS LOGICAL   NO-UNDO INIT FALSE.
        DEFINE VARIABLE cDirection   AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cFilters     AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cFilter      AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cFields      AS CHARACTER NO-UNDO EXTENT.
        DEFINE VARIABLE cField       AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cDBField     AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cWhere       AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cType        AS CHARACTER NO-UNDO.
        DEFINE VARIABLE lChange      AS LOGICAL   NO-UNDO.
        DEFINE VARIABLE lOK          AS LOGICAL   NO-UNDO.
        
        DEFINE VARIABLE oRecords     AS JsonArray NO-UNDO.
        
        outilitiesHandler = NEW utilitiesHandler().
        
        //
        //  Ermitteln des Tabellennamens, ob die Tabelle das Feld "company" und/oder das Feld "active" enthält
        outilitiesHandler:evaluateFile(
            INPUT  oJsonIdent   ,
            OUTPUT cFileName    ,
            OUTPUT lCompany     ,
            OUTPUT lActive      ,
            OUTPUT lWordindex
            ).
            
        cFieldReplace    = SUBSTITUTE('&1_', cFileName).
        cKeyFieldReplace = SUBSTITUTE('keyfield_&1_', cFileName).
        cFilterReplace   = SUBSTITUTE('filter_&1_', cFileName).
        
        lOK = outilitiesHandler:getKeyFields(
            INPUT  oJsonIdent   ,
            OUTPUT cKeyFields   ,
            OUTPUT cKeyValues
            ).
        
        CREATE BUFFER hBuffer FOR TABLE cFileName.
        
        cuser_name = oJsonIdent:GetCharacter('user_name').
        ccompany   = oJsonIdent:GetCharacter('company').
        lChange    = (IF oJsonIdent:HAS('change') THEN TRUE ELSE FALSE).
        cSortField = ''.
        cDirection = ''.
        cWhere     = ''.
        iStartPage = 1.
        IF oJsonIdent:HAS('page') THEN iStartPage = INTEGER(oJsonIdent:GetCharacter('page')) NO-ERROR.
        iStartRecord = ((iStartPage - 1) * iMaxRecords) + 1. 
        
        IF oJsonIdent:HAS('search') THEN 
        DO:
            cSearchChars = oJsonIdent:GetCharacter('search').
            cSearchChars = REPLACE(cSearchChars, '+', ' ').
            lSearch      = TRUE.
            iMaxRecords  = 100.
            iStartRecord = 1.
        END.
        
        IF lCompany THEN cWhere = SUBSTITUTE('WHERE &1.company = &2', cFileName, QUOTER(ccompany)).
        IF cKeyFields <> '' THEN 
        DO:
            DO ii = 1 TO NUM-ENTRIES(cKeyFields, ';'):
                cString = ENTRY(ii, cKeyFIelds, ';').
                cString = REPLACE(cString, cKeyFieldReplace, '').
                cString = REPLACE(cString, cFieldReplace, '').
                IF cString = 'company' AND lCompany THEN NEXT.
                cValue  = ENTRY(ii, cKeyValues, CHR(01)). 
                cString = SUBSTITUTE('&1.&2 = &3 ', cFileName, cString, cValue).
                cWhere  = cWhere + (IF cWhere = '' THEN 'WHERE ' ELSE ' AND ') + cString.
            END.
        END.
        outilitiesHandler:writeStartcWhere(
            INPUT  oJsonIdent,
            INPUT  cFileName ,
            INPUT  cWhere
            ).
// MESSAGE 'Start - cWhere ' cWhere.
        IF lSearch THEN
        DO:
            DO ii = 1 TO NUM-ENTRIES(cSearchChars, ' '):
                cValue     = ENTRY(ii, cSearchChars, ' ').
                iNumerisch = INTEGER(cValue) NO-ERROR.
                cWhere = cWhere + (IF cWhere = '' THEN ' WHERE ' ELSE 'AND ').
                IF  NOT ERROR-STATUS:ERROR AND
                    iNumerisch > 0         THEN cValue = SUBSTITUTE('&1&2&1', CHR(01), TRIM(STRING(iNumerisch,'>>>>>>>>9-'))).
                cWhere = cWhere + 'LOOKUP(' + QUOTER(cValue) + ', ' + cFileName + '.wordindex, " ") > 0 '. 
            END.
        END.
        ELSE 
        DO: 
            IF oJsonIdent:HAS('sortField') THEN 
            DO:
                cSortField = REPLACE(oJsonIdent:GetCharacter('sortField'), cFieldReplace, '').
                cDirection = oJsonIdent:GetCharacter('sortDirection').
            END.
              
            outilitiesHandler:writeSortfields(
                INPUT  oJsonIdent,
                INPUT  cFileName ,
                INPUT  cSortField ,
                INPUT  cDirection 
                ).
        
            cFields = oJsonIdent:GetNames().
            DO i1 = 1 TO EXTENT(cFields):
                cField = cFields[i1].
                IF NOT cField BEGINS 'filter_' THEN NEXT. 
                cFilter = oJsonIdent:GetCharacter(cField).
                cField  = REPLACE(cField, cFilterReplace, '').
                cType   = hBuffer:BUFFER-FIELD(cField):DATA-TYPE.
                CASE cType:
                    WHEN 'character' THEN 
                        cFilter = QUOTER(cFilter).
                    WHEN 'logical'   THEN 
                        cFilter = STRING(cFilter,'yes/no').
                    WHEN 'date'      THEN 
                        cFilter = STRING(DATE(cFilter),'99.99.9999').
                END CASE.
                cDBField = SUBSTITUTE('&1.&2', cFileName, cField).
                cWhere = cWhere
                    + (IF cWhere = '' THEN 'WHERE ' ELSE 'AND ')
                    + 'INDEX(' + cDBField + ', ' + cFilter + ') > 0 '.
            END.
        END.
// MESSAGE 'cWhere = ' cWhere.

        IF NOT cDirection BEGINS 'des' THEN cDirection = ''.
        IF cSortField <> '' THEN cWhere = cWhere + 'BY ' + cSortField + ' ' + cDirection.
         
        CREATE TEMP-TABLE ttTable.
        ttTable:ADD-FIELDS-FROM (cFilename, 'wordindex').
        IF cSortField <> '' THEN 
        DO:
            ttTable:ADD-NEW-INDEX ('ttTable-k1', FALSE, TRUE).     /*  UNIQUE, PRIMARY */
            IF cDirection BEGINS 'des' THEN ttTable:ADD-INDEX-FIELD ('ttTable-k1', cSortField, 'desc').
            ELSE                            ttTable:ADD-INDEX-FIELD ('ttTable-k1', cSortField).
        END.
        ttTable:TEMP-TABLE-PREPARE ('records').
        httTable = ttTable:DEFAULT-BUFFER-HANDLE.
         
        DO ii = 1 TO httTable:NUM-FIELDS:
            httTable:BUFFER-FIELD(ii):SERIALIZE-NAME = cFileName + '_' + httTable:BUFFER-FIELD(ii):NAME NO-ERROR.
        END.
// MESSAGE 'cWhere beim Start des lesens ' cWhere.
        ii = 0.
        i1 = 0.
        ttTable:EMPTY-TEMP-TABLE ().
        CREATE QUERY hQuery.
        cWhere = SUBSTITUTE('FOR EACH &1 NO-LOCK &2 ', cFileName, cWhere) NO-ERROR.
// MESSAGE 'writeLastcWhere fuer Datei' cFileName 'ist' cWhere.
        outilitiesHandler:writeLastcWhere(
            INPUT  oJsonIdent ,
            INPUT  cFileName  ,
            INPUT  cWhere
            ).
        MESSAGE 'cWhere vor replacing ' cWhere.
        cWhere = REPLACE(cWhere, 'FOR', 'PRESELECT').         
        MESSAGE 'cWhere nach replacing ' cWhere.
        hQuery:SET-BUFFERS (hBuffer) NO-ERROR.
        hQuery:QUERY-PREPARE (cWhere) NO-ERROR.
        hQuery:QUERY-OPEN ().
        /*        hQuery:GET-LAST ().*/
        MESSAGE 'Azzahl Query-Datensaetze = ' hQuery:NUM-RESULTS.
        hQuery:GET-FIRST ().

        iCurrentPosition = 0.
        DO WHILE NOT hQuery:QUERY-OFF-END:
            ii = ii + 1.
            IF ii < iStartRecord THEN 
            DO:
                hQuery:GET-NEXT ().
                NEXT.
            END.
            IF iCurrentPosition = 0 THEN iCurrentPosition = ii.
            i1 = i1 + 1.
            IF i1 <= iMaxRecords THEN 
            DO:
                httTable:BUFFER-CREATE().
                httTable:BUFFER-COPY(hBuffer).
            END.
            hQuery:GET-NEXT ().
        END.
        hQuery:QUERY-CLOSE ().
        DELETE OBJECT hBuffer NO-ERROR.

        iPageCounter = ii / iMaxRecords.
        IF (iPageCounter * iMaxRecords) < ii THEN iPageCounter = iPageCounter + 1.  
        oRecords = NEW JsonArray().
        httTable:WRITE-JSON('JsonArray', oRecords).

        oJsonReturn = NEW JsonObject().
        oJsonReturn:ADD('records'   , oRecords).
        oJsonReturn:ADD('maxRecords', ii).
        oJsonReturn:ADD('pageCount' , iPageCounter).
        outilitiesHandler:writePosition(
            INPUT  oJsonIdent       ,
            INPUT  cFileName        ,
            INPUT  iCurrentPosition 
            ).
        oJsonReturn:WriteFile('C:\TEMP\getData_messages.json', TRUE).
        lRetVal = TRUE.        
        RETURN lRetVal.

    END METHOD.

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

    METHOD PUBLIC LOGICAL rebuildData(
        INPUT  oJsonIdent  AS JsonObject,
        OUTPUT oJsonReturn AS JsonObject  
        ):
        
        DEFINE VARIABLE ii           AS INTEGER   NO-UNDO.
        DEFINE VARIABLE i1           AS INTEGER   NO-UNDO.
        DEFINE VARIABLE iNumerisch   AS INTEGER   NO-UNDO.
        DEFINE VARIABLE lRetVal      AS LOGICAL   NO-UNDO.
        DEFINE VARIABLE cSortField   AS CHARACTER NO-UNDO INIT ''.
        DEFINE VARIABLE cSearchChars AS CHARACTER NO-UNDO INIT ''.
        DEFINE VARIABLE cValue       AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cDirection   AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cFields      AS CHARACTER NO-UNDO EXTENT.
        DEFINE VARIABLE cField       AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cDBField     AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cWhere       AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cType        AS CHARACTER NO-UNDO.
        DEFINE VARIABLE lOK          AS LOGICAL   NO-UNDO.
        DEFINE VARIABLE rBuffer      AS RECID     NO-UNDO.
        
        outilitiesHandler = NEW utilitiesHandler().

        outilitiesHandler:evaluateFile(
            INPUT  oJsonIdent   ,
            OUTPUT cFileName    ,
            OUTPUT lCompany     ,
            OUTPUT lActive      ,
            OUTPUT lWordindex
            ).
            
        cFieldReplace    = SUBSTITUTE('&1_'         , cFileName).
        cKeyFieldReplace = SUBSTITUTE('keyfield_&1_', cFileName).
        cFilterReplace   = SUBSTITUTE('filter_&1_'  , cFileName).
        
        lOK = outilitiesHandler:getKeyFields(
            INPUT  oJsonIdent   ,
            OUTPUT cKeyFields   ,
            OUTPUT cKeyValues
            ).
        
        CREATE BUFFER hBuffer FOR TABLE cFileName.
        
        cuser_name = oJsonIdent:GetCharacter('user_name').
        ccompany   = oJsonIdent:GetCharacter('company').
        
        cSortField   = ''.
        cDirection   = ''.
        cWhere       = ''.
        cPrimaryKey  = ''.
        iStartPage   = 1.
        iStartRecord = 1. 
        
        IF lCompany THEN cWhere = SUBSTITUTE('WHERE &1.company = &2', cFileName, QUOTER(ccompany)).
        IF cKeyFields <> '' THEN 
        DO:
            DO ii = 1 TO NUM-ENTRIES(cKeyFields, ';'):
                cString = ENTRY(ii, cKeyFIelds, ';').
                cString = REPLACE(cString, cKeyFieldReplace, '').
                cString = REPLACE(cString, cFieldReplace, '').
                IF cString = 'company' THEN NEXT.
                cString = SUBSTITUTE('&1.&2 = &3 ', cFileName, cString, ENTRY(ii, cKeyValues, CHR(01))).
                cPrimaryKey = cPrimaryKey + (IF cPrimaryKey = '' THEN 'WHERE ' ELSE 'AND ') + cString.
            END.
        END.
        
        outilitiesHandler:readStartcWhere(
            INPUT  oJsonIdent,
            INPUT  cFileName ,
            OUTPUT cWhere
            ).
        
        outilitiesHandler:readSortFields(
            INPUT  oJsonIdent,
            INPUT  cFileName ,
            OUTPUT cSortField,
            OUTPUT cDirection).
        
        IF cSortField <> '' THEN cWhere = cWhere + ' BY ' + cSortField + ' ' + cDirection.
         
        CREATE TEMP-TABLE ttTable.
        ttTable:ADD-FIELDS-FROM (cFilename, 'wordindex').
        IF cSortField <> '' THEN 
        DO:
            ttTable:ADD-NEW-INDEX   ('ttTable-k1', FALSE, TRUE).     /*  UNIQUE, PRIMARY */
            ttTable:ADD-INDEX-FIELD ('ttTable-k1', cSortField, cDirection).
        END.
        ttTable:TEMP-TABLE-PREPARE ('records').
        httTable = ttTable:DEFAULT-BUFFER-HANDLE.
         
        DO ii = 1 TO httTable:NUM-FIELDS:
            httTable:BUFFER-FIELD(ii):SERIALIZE-NAME = cFileName + '_' + httTable:BUFFER-FIELD(ii):NAME NO-ERROR.
        END.
        MESSAGE 'cWhere beim Start des lesens ' cWhere.
        ASSIGN 
            ii               = 0
            i1               = 0
            iActualPage      = 0
            iCurrentPosition = 0.
        hBuffer:FIND-UNIQUE(cPrimaryKey, NO-LOCK) NO-ERROR.
        rBuffer = hBuffer:RECID.
        
        ttTable:EMPTY-TEMP-TABLE ().
        CREATE QUERY hQuery.
        cWhere = SUBSTITUTE('FOR EACH &1 NO-LOCK &2 ', cFileName, cWhere) NO-ERROR.
        hQuery:SET-BUFFERS (hBuffer) NO-ERROR.
        hQuery:QUERY-PREPARE (cWhere) NO-ERROR.
        hQuery:QUERY-OPEN ().
        hQuery:GET-FIRST ().
        MESSAGE 'cPrimaryKey = ' cPrimaryKey '- cWhere = ' cWhere.
        lOK = FALSE.
        DO WHILE NOT hQuery:QUERY-OFF-END:
            ii = ii + 1.
            IF ii < iStartRecord THEN 
            DO:
                hQuery:GET-NEXT ().
                NEXT.
            END.
            IF  NOT lOK                AND
                ii MOD iMaxRecords = 1 THEN iActualPage = iActualPage + 1.
            IF NOT lOK THEN 
            DO:
                IF hBuffer:RECID <> rBuffer THEN 
                DO:
                    hQuery:GET-NEXT().
                    NEXT.
                END.
                iIndex = ii MOD iMaxRecords.
                iStartIndex = ii - iIndex + 1.
                DO WHILE ii > iStartIndex:
                    hQuery:GET-PREV ().
                    ii = ii - 1.
                END.
                lOK = TRUE.
            END.
            IF iCurrentPosition = 0 THEN iCurrentPosition = ii.
            i1 = i1 + 1.
            IF i1 <= iMaxRecords THEN 
            DO:
                httTable:BUFFER-CREATE().
                httTable:BUFFER-COPY(hBuffer).
            END.
            hQuery:GET-NEXT ().
        END.
        hQuery:QUERY-CLOSE ().
        DELETE OBJECT hBuffer NO-ERROR.
        
        IF ii = 0 THEN RETURN FALSE.

        iPageCounter = ii / iMaxRecords.
        IF (iPageCounter * iMaxRecords) < ii THEN iPageCounter = iPageCounter + 1. 
 
        oJsonPosition = NEW JsonObject().
        oJsonPosition:ADD('page' , iActualPage).
        oJsonPosition:ADD('index', iIndex - 1).     /* -1 weil in Java beginnt Index bei 0  */
        
        oRecords = NEW JsonArray().
        httTable:WRITE-JSON('JsonArray', oRecords).
        
        oJsonReturn = NEW JsonObject().
        oJsonReturn:ADD('records'   , oRecords).
        oJsonReturn:ADD('maxRecords', ii).
        oJsonReturn:ADD('pageCount' , iPageCounter).
        oJsonReturn:ADD('position'  , oJsonPosition).
        outilitiesHandler:writePosition(
            INPUT  oJsonIdent       ,
            INPUT  cFileName        ,
            INPUT  iCurrentPosition 
            ).
            
        lRetVal = TRUE.        
        RETURN lRetVal.

    END METHOD.

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

    METHOD PUBLIC LOGICAL updateData(
        INPUT  oJsonIdent  AS JsonObject,
        INPUT  oJsonRecord AS jsonObject,
        OUTPUT oJsonReturn AS JsonObject  
        ):
    
        DEFINE VARIABLE oJsonMessage  AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonPosition AS JsonObject NO-UNDO.

        DEFINE VARIABLE lRetVal       AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE lOK           AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE ii            AS INTEGER    NO-UNDO.
        DEFINE VARIABLE i1            AS INTEGER    NO-UNDO.
        DEFINE VARIABLE iIndex        AS INTEGER    NO-UNDO.
        DEFINE VARIABLE cWordIndex    AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cSortField    AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cDirection    AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE hField        AS HANDLE     NO-UNDO.
        DEFINE VARIABLE htField       AS HANDLE     NO-UNDO.
        DEFINE VARIABLE cField        AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cValue        AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cIndexFields  AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE rBuffer       AS RECID      NO-UNDO.

        outilitiesHandler = NEW utilitiesHandler().

        outilitiesHandler:evaluateFile(
            INPUT  oJsonIdent   ,
            OUTPUT cFileName    ,
            OUTPUT lCompany     ,
            OUTPUT lActive      ,
            OUTPUT lWordindex
            ).
            
        cFieldReplace    = SUBSTITUTE('&1_', cFileName).
        cKeyFieldReplace = SUBSTITUTE('keyfield_&1_', cFileName).
        cFilterReplace   = SUBSTITUTE('filter_&1_', cFileName).
        cFileReplace     = SUBSTITUTE('&1_', cFileName).
        iLanguage_id     = oJsonIdent:GetInteger('language_id').
        ccompany         = oJsonIdent:GetCharacter('company').

        lOK = outilitiesHandler:getKeyFields(
            INPUT  oJsonIdent   ,
            OUTPUT cKeyFields   ,
            OUTPUT cKeyValues
            ).

        CREATE TEMP-TABLE ttTable.
        ttTable:ADD-FIELDS-FROM (cFileName, 'wordindex'). /*  except Field wordindex  */
        ttTable:TEMP-TABLE-PREPARE ('record').
        httTable = ttTable:DEFAULT-BUFFER-HANDLE.

        DO ii = 1 TO httTable:NUM-FIELDS:
            httTable:BUFFER-FIELD(ii):SERIALIZE-NAME = cFileName + '_' + httTable:BUFFER-FIELD(ii):NAME NO-ERROR.
        END.

        httTable:READ-JSON('JsonObject', oJsonRecord) NO-ERROR.
        httTable:FIND-FIRST('', NO-LOCK).

        //  Primary-Index-Fields für WHERE-Statement        
        CREATE BUFFER hBuffer FOR TABLE cFileName.
        cIndexFields = outilitiesHandler:getPrimaryIndexFields(
            INPUT cFileName
            ).

        //  Erzeugen von Where-Statement für UNIQUE-Find
        cWhere = ''.    
        DO i1 = 1 TO NUM-ENTRIES(cIndexFields, ';'):
            cField = ENTRY(i1, cIndexFields, ';').
            hField = httTable:BUFFER-FIELD(cField):HANDLE.
            CASE hField:DATA-TYPE:
                WHEN 'character' THEN 
                    cValue = QUOTER(hField:BUFFER-VALUE).
                WHEN 'logical'   THEN 
                    cValue = STRING(hField:BUFFER-VALUE,"TRUE/FALSE").
                WHEN 'date'      THEN 
                    cValue = STRING(DATE(hField:BUFFER-VALUE)).
                OTHERWISE             
                cValue = hField:BUFFER-VALUE. 
            END CASE.
            cWhere = cWhere
                + (IF cWhere = '' THEN 'WHERE ' ELSE ' AND ')
                + SUBSTITUTE('&1.&2 = ', cFileName, cField)
                + cValue.
        END.

        lRetVal = FALSE.
        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
            lOK = hBuffer:FIND-UNIQUE(cWhere) NO-ERROR. 
            IF NOT hBuffer:AVAILABLE THEN 
            DO:
                outilitiesHandler:getErrorMessage(
                    INPUT  '1014',
                    INPUT  ilanguage_id,
                    INPUT  '',
                    OUTPUT lcMessage).
                LEAVE.
            END.

            DO ii = 1 TO httTable:NUM-FIELDS:
                hField  = hBuffer:BUFFER-FIELD(ii):HANDLE NO-ERROR.
                IF  ERROR-STATUS:ERROR       OR
                    NOT VALID-HANDLE(hField) THEN NEXT.
                    
                htField = httTable:BUFFER-FIELD(ii):HANDLE NO-ERROR.
                IF htField:BUFFER-VALUE = hField:BUFFER-VALUE THEN NEXT.
                hField:BUFFER-VALUE = htField:BUFFER-VALUE. 
            END.
            
            hField = hBuffer:BUFFER-FIELD('updated_at'):HANDLE NO-ERROR.
            IF  NOT ERROR-STATUS:ERROR AND
                VALID-HANDLE(hField)   THEN hField:BUFFER-VALUE = NOW.
            
            hField = hBuffer:BUFFER-FIELD('wordindex'):HANDLE NO-ERROR.
            IF  NOT ERROR-STATUS:ERROR AND
                VALID-HANDLE(hField)   THEN 
            DO:
                cWordIndex = outilitiesHandler:createWordindex(
                    INPUT hBuffer
                    ).
                hField:BUFFER-VALUE = cWordIndex.
            END.
            rBuffer = hBuffer:RECID.
            
            oJsonReturn = NEW JsonObject().
            oJsonData   = NEW JsonObject().
            oJsonArray  = NEW JsonArray ().
            httTable:BUFFER-COPY(hBuffer).
            httTable:WRITE-JSON('JsonObject', oJsonData).
    
            oJsonArray = oJsonData:GetJsonArray('record').
            oJsonData  = oJsonArray:GetJsonObject(1). 
            oJsonReturn:ADD('record', oJsonData).
            
            hBuffer:BUFFER-RELEASE ().
            
            outilitiesHandler:readSortFields(
                INPUT  oJsonIdent ,
                INPUT  cFileName  ,
                OUTPUT cSortField ,
                OUTPUT cDirection ).

            //  Where-Statement f�r FOR EACH Filename f�r die Anzeige            
            cWhere  = ''.
            IF lCompany THEN cWhere = SUBSTITUTE('WHERE &1.company = &2', cFileName, QUOTER(ccompany)).
            IF cKeyFields <> '' THEN
            DO:
                DO ii = 1 TO NUM-ENTRIES(cKeyFields, ';'):
                    cField = ENTRY(ii, cKeyFields, ';').
                    cField = REPLACE(cField, cKeyFieldReplace, '').
                    cField = REPLACE(cField, cFilterReplace, '').
                    cField = REPLACE(cField, cFileReplace, '').
                    IF  lCompany           AND 
                        cField = 'company' THEN NEXT.
                    cValue = ENTRY(ii, cKeyValues, CHR(01)).
                    cWhere = cWhere
                        + (IF cWhere = '' THEN 'WHERE &1.&2 = &3' ELSE ' AND &1.&2 = &3').
                    cWhere = SUBSTITUTE(cWhere, cFileName, cField, cValue).
                END.
            END.
            
            CREATE QUERY hQuery.
            hQuery:SET-BUFFERS (hBuffer).
            cWhere = SUBSTITUTE('FOR EACH &1 NO-LOCK &2 ', cFileName, cWhere).
            IF cSortField <> '' THEN cWhere = cWhere + ' BY ' + cSortField + ' ' + cDirection.

            hQuery:QUERY-PREPARE(cWhere).
            hQuery:QUERY-OPEN().
            hQuery:GET-FIRST().
            
            ii = 0.
            i1 = 0.  
            DO WHILE NOT hQuery:QUERY-OFF-END:
                ii = ii + 1.
                IF hBuffer:RECID = rBuffer THEN i1 = ii.
                hQuery:GET-NEXT ().
            END.
            hQuery:QUERY-CLOSE ().
        
            iPageCounter = i1 / iMaxRecords.
            IF (iPageCounter * iMaxRecords) < i1 THEN iPageCounter = iPageCounter + 1.

            iIndex = i1 MOD iMaxRecords.
            IF iIndex = 0 THEN iIndex = iMaxRecords.
                          
            oJsonPosition = NEW JsonObject().
            oJsonPosition:ADD('page', iPageCounter).
            oJsonPosition:ADD('index', iIndex - 1).     /* -1 weil in Java beginnt Index bei 0  */
            oJsonPosition:ADD('totalRecords', ii).
            
            oJsonReturn:ADD('position', oJsonPosition).

            lRetVal = TRUE.
            LEAVE.
        END.
        
        IF NOT lRetVal THEN 
        DO:
            oJsonMessage = NEW JsonObject().
            oJsonMessage:ADD('success', FALSE).
            oJsonMessage:ADD('message', lcMessage).
            oJsonMessage:WRITE(lcJsonString, FALSE).
            
            oJsonReturn = oJsonMessage.
        END.
        
        RETURN lRetVal.

        CATCH e AS Progress.Lang.Error:

        END CATCH.

        FINALLY:

        END FINALLY.

    END METHOD.

    DESTRUCTOR PUBLIC adminprogsHandler ( ):

    END DESTRUCTOR.

END CLASS.