 
/*------------------------------------------------------------------------
   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.

CLASS admin.usersHandler 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 iMaxRecords  AS INTEGER           NO-UNDO INIT 5.
    DEFINE VARIABLE iStartPage   AS INTEGER           NO-UNDO.
    DEFINE VARIABLE iStartRecord AS INTEGER           NO-UNDO.
    DEFINE VARIABLE iPageCounter AS INTEGER           NO-UNDO.
    
    DEFINE VARIABLE httusers     AS HANDLE            NO-UNDO.
    DEFINE VARIABLE ttusers      AS HANDLE            NO-UNDO.
    
    DEFINE VARIABLE hQuery       AS HANDLE            NO-UNDO.
    DEFINE VARIABLE hBuffer      AS HANDLE            NO-UNDO.
    
    DEFINE BUFFER busers FOR users.
         
    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 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 cWhere        AS CHARACTER  NO-UNDO.

        outilitiesHandler = NEW utilitiesHandler().
        
        CREATE TEMP-TABLE ttusers.
        ttusers:ADD-FIELDS-FROM ('users', 'wordindex'). /*  except Field wordindex  */
        ttusers:TEMP-TABLE-PREPARE ('record').
        httusers = ttusers:DEFAULT-BUFFER-HANDLE.

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

        httusers:READ-JSON('JsonObject', oJsonRecord) NO-ERROR.
        httusers:FIND-FIRST('', NO-LOCK).
        hBuffer = BUFFER busers:HANDLE.
        cuser_name = httusers:BUFFER-FIELD('user_name'):BUFFER-VALUE.

        lRetVal = FALSE.
                
        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
            FIND FIRST users NO-LOCK 
                WHERE users.user_name = cuser_name NO-ERROR.
            IF AVAILABLE users THEN LEAVE.

            CREATE  busers.
            hBuffer = BUFFER busers:HANDLE.        
            DO ii = 1 TO httusers:NUM-FIELDS:
                // IF httusers:BUFFER-FIELD(ii):BUFFER-VALUE = hBuffer:BUFFER-FIELD(ii):BUFFER-VALUE THEN NEXT.
                hBuffer:BUFFER-FIELD(ii):BUFFER-VALUE = httusers:BUFFER-FIELD(ii):BUFFER-VALUE. 
            END.
            busers.created_at = NOW.
            cWordIndex = outilitiesHandler:createWordindex(
                INPUT hBuffer
                ).
            busers.wordindex = cWordIndex.
            
            oJsonReturn = NEW JsonObject().
            oJsonData   = NEW JsonObject().
            oJsonArray  = NEW JsonArray ().
            httusers:BUFFER-COPY(hBuffer).
            httusers:WRITE-JSON('JsonObject', oJsonData).
    
            oJsonArray = oJsonData:GetJsonArray('record').
            oJsonData  = oJsonArray:GetJsonObject(1). 
            oJsonReturn:ADD('record', oJsonData).
            
            RELEASE busers.
            
            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     = 'users' 
                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 = ''.
            
            hBuffer = BUFFER users:HANDLE.
            CREATE QUERY hQuery.
            hQuery:SET-BUFFERS (hBuffer).
            cWhere = 'FOR EACH users NO-LOCK '.
            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:BUFFER-FIELD('user_name'):BUFFER-VALUE = cuser_name 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:WRITE(lcJsonString, FALSE).
        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 lRetVal       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 cSortField    AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cDirection    AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cWhere        AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE rUsers        AS RECID      NO-UNDO.
        
        DEFINE VARIABLE oJsonPosition AS JsonObject NO-UNDO.

        outilitiesHandler = NEW utilitiesHandler().
        
        CREATE TEMP-TABLE ttusers.
        ttusers:ADD-FIELDS-FROM ('users', 'wordindex'). /*  except Field wordindex  */
        ttusers:TEMP-TABLE-PREPARE ('record').
        httusers = ttusers:DEFAULT-BUFFER-HANDLE.
         
        DO ii = 1 TO httusers:NUM-FIELDS:
            httusers:BUFFER-FIELD(ii):SERIALIZE-NAME = 'users_' + httusers:BUFFER-FIELD(ii):NAME NO-ERROR.
        END.

        httusers:READ-JSON('JsonObject', oJsonRecord) NO-ERROR.
        httusers:FIND-FIRST('', NO-LOCK).
        hBuffer = BUFFER busers:HANDLE.
        cuser_name = httusers:BUFFER-FIELD('user_name'):BUFFER-VALUE.
        
        lRetVal = FALSE.
        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
            FIND FIRST users NO-LOCK 
                WHERE users.user_name = cuser_name NO-ERROR.
            IF NOT AVAILABLE users THEN LEAVE.
            rUsers = RECID(users).

            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     = 'users' 
                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 = ''.
            
            hBuffer = BUFFER users:HANDLE.
            CREATE QUERY hQuery.
            hQuery:SET-BUFFERS (hBuffer).
            cWhere = 'FOR EACH users NO-LOCK '.
            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:BUFFER-FIELD('user_name'):BUFFER-VALUE = cuser_name 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.
            
            FIND users WHERE RECID(users) = rUsers.
            DELETE users.
            RELEASE users.
                          
            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 cKeyFields        AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cKeyValues        AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE lcJsonString      AS LONGCHAR   NO-UNDO.
        DEFINE VARIABLE cWhere            AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cString           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_', ''),
                    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 lRetVal      AS LOGICAL   NO-UNDO.
        DEFINE VARIABLE cSortField   AS CHARACTER NO-UNDO INIT ''.
        DEFINE VARIABLE cSearchChars AS CHARACTER NO-UNDO INIT ''.
        DEFINE VARIABLE lSearch      AS LOGICAL   NO-UNDO.
        DEFINE VARIABLE cValue       AS CHARACTER NO-UNDO.
        DEFINE VARIABLE lWordIndex   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 dDate        AS DATE      NO-UNDO.
        
        DEFINE VARIABLE oRecords     AS JsonArray NO-UNDO.
        
        CREATE BUFFER hBuffer FOR TABLE 'users'.
        
        cuser_name = oJsonIdent:GetCharacter('user_name').
        ccompany   = oJsonIdent:GetCharacter('company').
        cSortField = ''.
        cDirection = ''.
        
        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 lWordIndex THEN
        DO:
            NEXTFIELD:
            DO ii = 1 TO NUM-ENTRIES(cSearchChars, '+'):
                cValue = ENTRY(ii, cSearchChars, '+').
                DO WHILE TRUE:
                    i1 = INTEGER(cValue) NO-ERROR.
                    IF  NOT ERROR-STATUS:ERROR AND
                        i1 > 0                 THEN 
                    DO:
                        cValue = SUBSTITUTE('"&1&2&1","&2"', CHR(01), TRIM(STRING(i1,'>>>>>>>>>9'))).
                        cWhere = cWhere + (IF cWhere = '' THEN 'WHERE ' ELSE 'AND (')
                            + '(LOOKUP(' + ENTRY(1, cValue, ',') + ', users.wordindex, " ") > 0 OR '
                            + 'LOOKUP(' + ENTRY(2, cValue, ',') + ', users.wordindex, " ") > 0) '. 
                        NEXT NEXTFIELD.
                    END.
                    dDate = DATE(cValue) NO-ERROR.
                    IF  NOT ERROR-STATUS:ERROR AND
                        dDate <> ?             THEN 
                    DO:
                        cValue = STRING(dDate,'99.99.9999').
                        LEAVE.
                    END.
                    cValue = QUOTER(cValue).
                    LEAVE.
                END.
                cWhere = cWhere + (IF cWhere = '' THEN 'WHERE ' ELSE 'AND ')
                    + 'LOOKUP(' + cValue + ', users.wordindex, " ") > 0 '. 
            END.
            // MESSAGE 'search mit Where' cWhere.
        END.
        ELSE 
        DO: 
            IF oJsonIdent:HAS('sortField') THEN 
            DO:
                cSortField = REPLACE(oJsonIdent:GetCharacter('sortField'), 'users_', '').
                cDirection = oJsonIdent:GetCharacter('sortDirection').
            END.
              
            REPEAT TRANSACTION ON ERROR UNDO, LEAVE:  
                FIND userdata
                    WHERE userdata.user_name   = cuser_name
                    AND   userdata.company     = ccompany
                    AND   userdata.branch      = '0000'
                    AND   userdata.record_type = 'sortField'
                    AND   userdata.section     = 'users' 
                    AND   userdata.key_type    = '' NO-ERROR.
              
                IF NOT AVAILABLE userdata THEN 
                DO:
                    CREATE  userdata.
                    ASSIGN 
                        userdata.user_name   = cuser_name
                        userdata.company     = ccompany
                        userdata.branch      = '0000'
                        userdata.record_type = 'sortField'
                        userdata.section     = 'users' 
                        userdata.key_type    = '' NO-ERROR.
                END.
                ASSIGN  
                    userdata.cfield_1 = cSortfield
                    userdata.cfield_2 = cDirection.
                RELEASE userdata.
                LEAVE.
            END.
        
            cFields = oJsonIdent:GetNames().
            cWhere  = ''.
            DO i1 = 1 TO EXTENT(cFields):
                cField = cFields[i1].
                IF NOT cField BEGINS 'filter_' THEN NEXT.
                 
                cFilter = oJsonIdent:GetCharacter(cField).
                cField  = REPLACE(cField, 'filter_users_', '').
                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('users.&1', cField).
                cWhere = cWhere
                    + (IF cWhere = '' THEN 'WHERE ' ELSE 'AND ')
                    + 'INDEX(' + cDBField + ', ' + cFilter + ') > 0 '.
            END.

            IF NOT cDirection BEGINS 'des' THEN cDirection = ''.
            IF cSortField <> '' THEN cWhere = cWhere + 'BY ' + cSortField + ' ' + cDirection.
        END.
         
        CREATE TEMP-TABLE ttusers.
        ttusers:ADD-FIELDS-FROM ('users', 'wordindex').
        IF cSortField <> '' THEN 
        DO:
            ttusers:ADD-NEW-INDEX ('ttuser-k1', FALSE, TRUE).     /*  UNIQUE, PRIMARY */
            IF cDirection BEGINS 'des' THEN ttusers:ADD-INDEX-FIELD ('ttUser-k1', cSortField, 'desc').
            ELSE                            ttusers:ADD-INDEX-FIELD ('ttUser-k1', cSortField).
        END.
        ttusers:TEMP-TABLE-PREPARE ('records').
        httusers = ttusers:DEFAULT-BUFFER-HANDLE.
         
        DO ii = 1 TO httusers:NUM-FIELDS:
            httusers:BUFFER-FIELD(ii):SERIALIZE-NAME = 'users_' + httusers:BUFFER-FIELD(ii):NAME NO-ERROR.
        END.
        ii = 0.
        i1 = 0.
        ttusers:EMPTY-TEMP-TABLE ().
        CREATE QUERY hQuery.
        hQuery:SET-BUFFERS (hBuffer) NO-ERROR.
        hQuery:QUERY-PREPARE (SUBSTITUTE('FOR EACH users NO-LOCK &1 ', cWhere)) NO-ERROR.
        hQuery:QUERY-OPEN ().
        hQuery:GET-FIRST ().

        DO WHILE NOT hQuery:QUERY-OFF-END:
            ii = ii + 1.
            IF ii < iStartRecord THEN 
            DO:
                hQuery:GET-NEXT ().
                NEXT.
            END.
            i1 = i1 + 1.
            IF i1 <= iMaxRecords THEN 
            DO:
                httusers:BUFFER-CREATE().
                httusers: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().
        httusers:WRITE-JSON('JsonArray', oRecords).
        
        oJsonReturn = NEW JsonObject().
        oJsonReturn:ADD('records'   , oRecords).
        oJsonReturn:ADD('maxRecords', ii).
        oJsonReturn:ADD('pageCount' , iPageCounter).

        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 lRetVal    AS LOGICAL   NO-UNDO.
        DEFINE VARIABLE ii         AS INTEGER   NO-UNDO.
        DEFINE VARIABLE cWordIndex AS CHARACTER NO-UNDO.

        outilitiesHandler = NEW utilitiesHandler().
        
        CREATE TEMP-TABLE ttusers.
        ttusers:ADD-FIELDS-FROM ('users', 'wordindex'). /*  except Field wordindex  */
        ttusers:TEMP-TABLE-PREPARE ('record').
        httusers = ttusers:DEFAULT-BUFFER-HANDLE.
         
        DO ii = 1 TO httusers:NUM-FIELDS:
            httusers:BUFFER-FIELD(ii):SERIALIZE-NAME = 'users_' + httusers:BUFFER-FIELD(ii):NAME NO-ERROR.
        END.

        httusers:READ-JSON('JsonObject', oJsonRecord) NO-ERROR.
        httusers:FIND-FIRST('', NO-LOCK).
        hBuffer = BUFFER busers:HANDLE.
        cuser_name = httusers:BUFFER-FIELD('user_name'):BUFFER-VALUE.
        
        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
            FIND busers
                WHERE busers.user_name = cuser_name NO-ERROR.
            DO ii = 1 TO httusers:NUM-FIELDS:
                IF httusers:BUFFER-FIELD(ii):BUFFER-VALUE = hBuffer:BUFFER-FIELD(ii):BUFFER-VALUE THEN NEXT.
                hBuffer:BUFFER-FIELD(ii):BUFFER-VALUE = httusers:BUFFER-FIELD(ii):BUFFER-VALUE. 
            END.
            busers.updated_at = NOW.
            cWordIndex = outilitiesHandler:createWordindex(
                INPUT hBuffer
                ).
            busers.wordindex = cWordIndex.
            
            oJsonReturn = NEW JsonObject().
            oJsonData   = NEW JsonObject().
            oJsonArray  = NEW JsonArray ().
            httusers:BUFFER-COPY(hBuffer).
            httusers:WRITE-JSON('JsonObject', oJsonData).
    
            oJsonArray = oJsonData:GetJsonArray('record').
            oJsonData  = oJsonArray:GetJsonObject(1). 
            oJsonReturn:ADD('record', oJsonData).
            
            RELEASE busers.
            lRetVal = TRUE.
            LEAVE.
        END.
        
        RETURN lRetVal.

        CATCH e AS Progress.Lang.Error:

        END CATCH.

        FINALLY:

        END FINALLY.

    END METHOD.

    DESTRUCTOR PUBLIC usersHandler ( ):

    END DESTRUCTOR.

END CLASS.