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


BLOCK-LEVEL ON ERROR UNDO, THROW.

USING OpenEdge.DataAdmin.IIndex FROM PROPATH.

USING Progress.Json.ObjectModel.JsonObject FROM PROPATH.
USING Progress.Json.ObjectModel.JsonArray FROM PROPATH.
USING Progress.Json.ObjectModel.ObjectModelParser FROM PROPATH.
USING Progress.Json.ObjectModel.JsonConstruct FROM PROPATH.

USING utilities.selectboxHandler FROM PROPATH.
USING utilities.utilitiesHandler FROM PROPATH.
USING src.ch.adprime.api.yourbarmate.beans.Response 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 oRecords         AS JsonArray         NO-UNDO.
    DEFINE VARIABLE oJsonPosition    AS JsonObject        NO-UNDO.
    DEFINE VARIABLE oJsonIdent       AS JsonObject        NO-UNDO.
    
    DEFINE VARIABLE cUser_Name       AS CHARACTER         NO-UNDO.
    DEFINE VARIABLE cCompany         AS CHARACTER         NO-UNDO.
    DEFINE VARIABLE iLanguage_id     AS INTEGER           NO-UNDO.
    DEFINE VARIABLE cFileName        AS CHARACTER         NO-UNDO.
    DEFINE VARIABLE cFunction        AS CHARACTER         NO-UNDO.
    DEFINE VARIABLE cProgram         AS CHARACTER         NO-UNDO.
    DEFINE VARIABLE cFormId          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 lBoxFields       AS LOGICAL           NO-UNDO.
    DEFINE VARIABLE iFormTabIndex    AS INTEGER           NO-UNDO.
    DEFINE VARIABLE lcJsonString     AS LONGCHAR          NO-UNDO.
        
    DEFINE VARIABLE cActiveSelection AS CHARACTER         NO-UNDO.
    DEFINE VARIABLE cSortField       AS CHARACTER         NO-UNDO INIT ''.
    DEFINE VARIABLE cDirection       AS CHARACTER         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 cString          AS CHARACTER         NO-UNDO.
    DEFINE VARIABLE cMessage         AS CHARACTER         NO-UNDO.
    DEFINE VARIABLE lcMessage        AS LONGCHAR          NO-UNDO.
    DEFINE VARIABLE lcString         AS LONGCHAR          NO-UNDO.
    DEFINE VARIABLE hError           AS HANDLE            NO-UNDO.
    
    DEFINE VARIABLE cWhere           AS CHARACTER         NO-UNDO.
    DEFINE VARIABLE cUniqueWhere     AS CHARACTER         NO-UNDO.
    
    DEFINE VARIABLE iAnzahlRecords   AS INTEGER           NO-UNDO.
    DEFINE VARIABLE iActualPage      AS INTEGER           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 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 TEMP-TABLE ttKeyFields
        FIELD iIndex     AS INTEGER 
        FIELD cLongName  AS CHARACTER 
        FIELD cFieldName AS CHARACTER 
        FIELD cFileName  AS CHARACTER 
        FIELD cValue     AS CHARACTER 
        FIELD cDataType  AS CHARACTER
        FIELD lKeyfield  AS LOGICAL
        
        INDEX ttKeyFields-k1 IS PRIMARY 
        iIndex
        cFieldName
        .
    DEFINE VARIABLE httKeyFields AS HANDLE NO-UNDO.
    
    DEFINE TEMP-TABLE ttPrimaryIndex
        FIELD iIndex     AS INTEGER 
        FIELD cFieldName AS CHARACTER 
        FIELD cFileName  AS CHARACTER 
        FIELD cValue     AS CHARACTER 
        FIELD cDataType  AS CHARACTER
        
        INDEX ttPrimaryIndex-k1 IS PRIMARY 
        iIndex
        cFieldName
        .
    DEFINE VARIABLE httPrimaryIndex AS HANDLE NO-UNDO.

    DEFINE TEMP-TABLE ttWordIndexTable
        FIELD cFileName  AS CHARACTER 
        FIELD cFieldName AS CHARACTER 
        FIELD cDataType  AS CHARACTER 
        FIELD cValue     AS CHARACTER
        .
        
    DEFINE VARIABLE ttJsonIdent       AS HANDLE           NO-UNDO.
    DEFINE VARIABLE htt               AS HANDLE           NO-UNDO.
    
    DEFINE VARIABLE outilitiesHandler AS utilitiesHandler NO-UNDO.
    DEFINE VARIABLE oselectboxHandler AS selectboxHandler NO-UNDO.
    
    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    CONSTRUCTOR PUBLIC adminprogsHandler (  ):
        SUPER ().
        
        hError = ERROR-STATUS:HANDLE.
        
    END CONSTRUCTOR.


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

    CONSTRUCTOR PUBLIC adminprogsHandler ( INPUT lcInput AS LONGCHAR, INPUT ipcFunction AS CHARACTER  ):
        SUPER ().
        
        DEFINE VARIABLE oParser    AS ObjectModelParser NO-UNDO.
        DEFINE VARIABLE oJsonCon   AS JsonConstruct     NO-UNDO.
        DEFINE VARIABLE cUsers     AS CHARACTER         NO-UNDO.
        DEFINE VARIABLE iItemsPage AS INTEGER           NO-UNDO.
        DEFINE VARIABLE cMaxHeight AS CHARACTER         NO-UNDO.
        
        hError = ERROR-STATUS:HANDLE.
        
        outilitiesHandler = NEW utilitiesHandler().
        oselectboxHandler = NEW selectboxHandler().
        
        oParser    = NEW ObjectModelParser().
        oJsonCon   = oParser:Parse(lcInput).
        oJsonIdent = CAST(oJsonCon, JsonObject).
        
        cProgram   = oJsonIdent:GetCharacter('program').
        cUsers     = oJsonIdent:GetCharacter('cUsers').
        iItemsPage = oJsonIdent:GetInteger  ('itemsPerPage').
        cMaxHeight = oJsonIdent:GetCharacter('tableMaxHeight').
        
        httKeyFields    = TEMP-TABLE ttKeyFields   :DEFAULT-BUFFER-HANDLE.
        httPrimaryIndex = TEMP-TABLE ttPrimaryIndex:DEFAULT-BUFFER-HANDLE.

        IF oJsonIdent:HAS('limit') THEN oJsonIdent:SET('limit', iItemsPage).
        ELSE                            oJsonIdent:ADD('limit', iItemsPage).
        //
        //  Ermitteln des Tabellennamens, ob die Tabelle das Feld "company" und/oder das Feld "active" enthält
        //
        outilitiesHandler:evaluateFile(
            INPUT-OUTPUT oJsonIdent     ,
            OUTPUT       cFileName      ,
            OUTPUT       lCompany       ,
            OUTPUT       lActive        ,
            OUTPUT       lWordIndex     ,
            INPUT-OUTPUT httKeyFields   ,
            INPUT-OUTPUT httPrimaryIndex
            ).
        oJsonIdent:write(lcString).
        //
        //  erstellen TEMP-TABLE aus oJsonObject mit dem HADLE htt
        //
        oJsonIdent:WRITE(lcInput, FALSE).
// MESSAGE STRING(lcInput).
        CREATE TEMP-TABLE ttJsonIdent.
        ttJsonIdent:READ-JSON('longchar', lcInput, 'EMPTY').
        ttJsonIdent:SERIALIZE-NAME = 'oJsonData'.
        htt = ttJsonIdent:DEFAULT-BUFFER-HANDLE.
        htt:FIND-FIRST ('', NO-LOCK).
        
        ASSIGN 
            cCompany     = htt::company
            cUser_Name   = htt::user_name
            iLanguage_id = htt::language_id
            cFileName    = htt::file_name
            cFormId      = htt::formId
            .
        
        CATCH e AS Progress.Lang.Error:

        END CATCH.

        FINALLY:

        END FINALLY.

    END CONSTRUCTOR.

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

    METHOD PUBLIC VOID buildWhere(
        ):

        DEFINE VARIABLE ii           AS INTEGER   NO-UNDO.
        DEFINE VARIABLE i1           AS INTEGER   NO-UNDO.
        DEFINE VARIABLE lOK          AS LOGICAL   NO-UNDO.
        DEFINE VARIABLE cValue       AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cString      AS CHARACTER NO-UNDO.
        DEFINE VARIABLE iNumerisch   AS INTEGER   NO-UNDO.
        
        DEFINE VARIABLE cSearchChars AS CHARACTER NO-UNDO INIT ''.
        DEFINE VARIABLE lSearch      AS LOGICAL   NO-UNDO.
        DEFINE VARIABLE cFields      AS CHARACTER NO-UNDO EXTENT.
        DEFINE VARIABLE cField       AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cFieldValue  AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cFilter      AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cDBField     AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cType        AS CHARACTER NO-UNDO.

        CREATE BUFFER hBuffer FOR TABLE cFileName.
        
        cSortField  = ''.
        cDirection  = ''.
        cWhere      = ''.
        iStartPage  = 1.    
        iMaxRecords = 25.
        IF oJsonIdent:HAS('page')  THEN iStartPage  = INTEGER(oJsonIdent:GetCharacter('page'))  NO-ERROR.
        IF oJsonIdent:HAS('limit') THEN iMaxRecords = INTEGER(oJsonIdent:GetCharacter('limit')) NO-ERROR.

        IF oJsonIdent:HAS('search') THEN 
        DO:
            cSearchChars = oJsonIdent:GetCharacter('search').
            cSearchChars = REPLACE(cSearchChars, '+', ' ').
            lSearch      = TRUE.
            iMaxRecords  = 100.
        END.
        iStartRecord = ((iStartPage - 1) * iMaxRecords) + 1.

        cString = 'WHERE'.
        FOR EACH ttKeyFields NO-LOCK:
            IF lSearch THEN 
            DO:
                IF  ttKeyFields.iIndex >  1 AND
                    ttKeyFields.iIndex < 99 THEN NEXT.
            END.
            IF ttKeyFields.cDataType = 'logical' AND ttKeyFields.cValue = '' THEN NEXT.
            CASE ttKeyFields.cDataType:
                WHEN 'integer' THEN 
                    cValue = ttKeyFields.cValue.
                WHEN 'int64' THEN 
                    cValue = ttKeyFields.cValue.
                WHEN 'decimal' THEN 
                    cValue = ttKeyFields.cValue.
                WHEN 'date' THEN 
                    cValue = STRING(DATE(ttKeyFields.cValue),'99.99.9999').
                WHEN 'logical' THEN 
                    cValue = STRING(LOGICAL(ttKeyFields.cValue),'true/false').
                WHEN 'character' THEN 
                    cValue = QUOTER(ttKeyFields.cValue).
            END CASE.
            IF ttKeyFields.lKeyfield OR ttKeyFields.cDataType = 'logical' THEN 
                cWhere = cWhere + SUBSTITUTE('&1 &2.&3 = &4 ', cString, ttKeyFields.cFileName, ttKeyFields.cFieldName, cValue).
            ELSE 
            DO:
                cWhere = cWhere + SUBSTITUTE('&1 INDEX(STRING(&2.&3), &4) > 0 ', cString, ttKeyFields.cFileName, ttKeyFields.cFieldName, QUOTER(STRING(cValue))).
            END.
            cString = 'AND'.
        END.
        //
        //  Suche aus dem Suchfeld -->  geht dann über Wordindex
        //
        IF lSearch THEN
        DO:
            DO ii = 1 TO NUM-ENTRIES(cSearchChars, ' '):
                cValue     = ENTRY(ii, cSearchChars, ' ').
                iNumerisch = INTEGER(cValue) NO-ERROR.
                IF NOT ERROR-STATUS:ERROR THEN cValue = SUBSTITUTE('&1&2&1', CHR(01), TRIM(STRING(iNumerisch,'>>>>>>>>9-'))).
                cWhere = cWhere + (IF cWhere = '' THEN ' WHERE ' ELSE 'AND ').
                cWhere = cWhere + 'LOOKUP(' + QUOTER(cValue) + ', ' + cFileName + '.wordindex, " ") > 0 '. 
            END.
        END.
        //
        //  hat es Sortierfelder ?
        //
        outilitiesHandler:readSortFields(
            INPUT  oJsonIdent   ,
            INPUT  cFileName    ,
            OUTPUT cSortField   ,
            OUTPUT cDirection
            ).
        IF cSortField <> '' THEN 
        DO:
            IF cDirection BEGINS 'asc' THEN cDirection = ''.
            cWhere = cWhere + SUBSTITUTE(' BY &1 &2', cSortField, cDirection).
        END.
// MESSAGE 'cWhere am Ende von BuildWhere =' cWhere.
        outilitiesHandler:writeLastcWhere(
            INPUT  oJsonIdent ,
            INPUT  cFileName  ,
            INPUT  cWhere
            ).

        createTempTable().

        RETURN.

    END METHOD.

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

    METHOD PUBLIC LOGICAL createBegin(
        INPUT  oJsonData     AS JsonObject   ,
        OUTPUT oJsonReturn   AS JsonObject
        ):
        MESSAGE "create begin".
        DEFINE VARIABLE oJsonMessage     AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonMessageBox  AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonRecord      AS JsonObject NO-UNDO.
        DEFINE VARIABLE oMasterKeyFields AS JsonObject NO-UNDO.

        DEFINE VARIABLE lRetVal          AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE lOK              AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE hField           AS HANDLE     NO-UNDO.
        DEFINE VARIABLE cField           AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cBufferField     AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cType            AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE ii               AS INTEGER    NO-UNDO.
        DEFINE VARIABLE iType            AS INTEGER    NO-UNDO.
        DEFINE VARIABLE iValue           AS INTEGER    NO-UNDO.
        DEFINE VARIABLE cValue           AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE lValue           AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE cFieldNames      AS CHARACTER  NO-UNDO EXTENT.
        
        DEFINE VARIABLE lcttTable        AS LONGCHAR   NO-UNDO.
        
        oJsonRecord = NEW JsonObject().
        oJsonRecord = oJsonData:GetJsonObject('record').
        
        oMasterKeyFields = NEW JsonObject().
        oMasterKeyFields = oJsonData:GetJsonObject('masterKeyfields') NO-ERROR.
        
        CREATE BUFFER hBuffer FOR TABLE cFileName.
        
        createTempTable().
        oJsonRecord:Write(lcttTable, FALSE).
        MESSAGE STRING(lcttTable).
        lOK = ttTable:READ-JSON('longchar', lcttTable, 'EMPTY') NO-ERROR.
        outilitiesHandler:evaluateErrorStatus(hError).
        httTable:FIND-FIRST('', NO-LOCK).

        IF lCompany THEN 
        DO:
            httTable::company = cCompany.
            oJsonRecord:SET(SUBSTITUTE('&1_&2', cFileName, 'company'), oJsonIdent:GetCharacter('company')).
        END.
        
        hField = httTable:BUFFER-FIELD('created_at') NO-ERROR.
        IF  NOT ERROR-STATUS:ERROR AND 
            VALID-HANDLE(hField) THEN 
        DO:
            hField:BUFFER-VALUE = NOW.
            IF INDEX(lcttTable, 'created_at') > 0 THEN oJsonRecord:SET(SUBSTITUTE('&1_&2', cFileName, 'created_at'), outilitiesHandler:date2iso(TODAY)).
        END.
              
        hField = httTable:BUFFER-FIELD('created_by') NO-ERROR.
        IF  NOT ERROR-STATUS:ERROR AND 
            VALID-HANDLE(hField) THEN 
        DO:
            hField:BUFFER-VALUE = oJsonIdent:GetCharacter('H_display_name').
            IF INDEX(lcttTable, 'created_by') > 0 THEN oJsonRecord:SET(SUBSTITUTE('&1_&2', cFileName, 'created_by'), oJsonIdent:GetCharacter('H_display_name')).
        END.
            
        EXTENT(cFieldNames) = ?.
        cFieldNames = oMasterKeyFields:GetNames() NO-ERROR.

        DO ii = 1 TO EXTENT(cFieldNames):
            cField       = cFieldNames[ii].
            cBufferField = cField.
            ENTRY(1, cBufferField, '_') = ''.
            cBufferField = SUBSTRING(cBufferField,02).
            hField       = httTable:BUFFER-FIELD(cBufferField):HANDLE NO-ERROR.
            cType        = hField:DATA-TYPE.
            lcString     = oMasterKeyFields:GetJsonText(cField).
            CASE cType:
                WHEN 'integer' THEN
                    hField:BUFFER-VALUE = INTEGER(lcString).
                WHEN 'int64' THEN
                    hField:BUFFER-VALUE = INT64(lcString).
                WHEN 'logical' THEN
                    hField:BUFFER-VALUE = LOGICAL(lcString).
                OTHERWISE
                hField:BUFFER-VALUE = lcString.
            END CASE.
        END.
        
        DELETE OBJECT oJsonRecord.
        
        oJsonRecord = NEW JsonObject().
        oJsonArray  = NEW JsonArray().
        httTable:WRITE-JSON ('JsonObject', oJsonRecord).
        oJsonArray  = oJsonRecord:GetJsonArray('record').
        oJsonRecord = oJsonArray:GetJsonObject(1).
        
        oJsonReturn = NEW JsonObject().
        oJsonReturn:ADD('success', TRUE).
        oJsonReturn:add('record', oJsonRecord).
// oJsonReturn:WriteFile('C:\TEMP\createBegin_jsonreturn_response.json', TRUE).

        lRetVal = TRUE.
        RETURN lRetVal.

    END METHOD.

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

    METHOD PUBLIC LOGICAL createData(
        INPUT  oJsonData   AS jsonObject,
        OUTPUT oJsonReturn AS JsonObject  
        ):
            
        DEFINE VARIABLE oJsonMessage     AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonMessageBox  AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonFieldErrors AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonRecord      AS JsonObject NO-UNDO.
        DEFINE VARIABLE oMasterKeyFields AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonSelectBoxes AS JsonObject NO-UNDO.

        DEFINE VARIABLE lRetVal          AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE lOK              AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE iAnzRec          AS INTEGER    NO-UNDO.
        DEFINE VARIABLE hField           AS HANDLE     NO-UNDO.
        DEFINE VARIABLE htField          AS HANDLE     NO-UNDO.
        DEFINE VARIABLE hUniqueBuffer    AS HANDLE     NO-UNDO.
        DEFINE VARIABLE cField           AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cValue           AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE rBuffer          AS RECID      NO-UNDO.
        DEFINE VARIABLE iContact_Id      AS INTEGER    NO-UNDO.
        DEFINE VARIABLE cFieldValue      AS CHARACTER  NO-UNDO.
        
        DEFINE VARIABLE lcttTable        AS LONGCHAR   NO-UNDO.

        oJsonRecord = NEW JsonObject().
        oJsonRecord = oJsonData:GetJsonObject('record') NO-ERROR.
// oJsonRecord:WriteFile('C:\TEMP\createData_record.json', TRUE).
        oMasterKeyFields = NEW JsonObject().
        oMasterKeyFields = oJsonData:GetJsonObject('masterKeyFields') NO-ERROR.
        
        CREATE BUFFER hBuffer FOR TABLE cFileName.
        
        createTempTable().
        oJsonRecord:Write(lcttTable, FALSE).
// MESSAGE STRING(lcttTable).
        lOK = ttTable:READ-JSON('longchar', lcttTable, 'EMPTY') NO-ERROR.
        outilitiesHandler:evaluateErrorStatus(hError).
        httTable:FIND-FIRST('', NO-LOCK).

        createUniqueWhere(
            INPUT  httTable,
            OUTPUT cUniqueWhere
            ).

        lRetVal = FALSE.
        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
            lOK = hBuffer:FIND-UNIQUE(cUniqueWhere, NO-LOCK) NO-ERROR.
            //
            //  Wenn gefunden, dann Fehler weil doppelte ID
            //
            IF lOK THEN 
            DO:
                outilitiesHandler:createErrorBox(
                    INPUT  oJsonIdent       ,
                    INPUT  '2007'           ,
                    INPUT  ''               ,
                    OUTPUT oJsonMessageBox
                    ).
                oJsonReturn = NEW JsonObject().
                oJsonReturn:ADD('success'     , FALSE          ).
                oJsonReturn:ADD('showMessage' , oJsonMessageBox).
                
                oJsonFieldErrors = NEW JsonObject().
                FOR EACH ttPrimaryIndex NO-LOCK:
                    cField = SUBSTITUTE('&1_&2', ttPrimaryIndex.cFileName, ttPrimaryIndex.cFieldName).
                    oJsonFieldErrors:ADD(cField, 'Doppelt').
                END.
                oJsonReturn:ADD('fieldErrors', oJsonFieldErrors).
                RETURN TRUE.
            END.
            //
            //  Datensatz erstellen / active setzen
            //
            hBuffer:BUFFER-CREATE().
            hBuffer:BUFFER-COPY(httTable) NO-ERROR.

            htField = hBuffer:BUFFER-FIELD('active'):HANDLE NO-ERROR.
            IF  NOT ERROR-STATUS:ERROR AND 
                VALID-HANDLE(htField)  THEN htField:BUFFER-VALUE = TRUE.
                
            htField = hBuffer:BUFFER-FIELD('created_at'):HANDLE NO-ERROR.
            IF  NOT ERROR-STATUS:ERROR AND 
                VALID-HANDLE(htField)  THEN htField:BUFFER-VALUE = NOW.
            htField = hBuffer:BUFFER-FIELD('created_by'):HANDLE NO-ERROR.
            IF  NOT ERROR-STATUS:ERROR AND 
                VALID-HANDLE(htField)  THEN htField:BUFFER-VALUE = oJsonIdent:GetCharacter('H_display_name').
                
            rBuffer = hBuffer:RECID.
            oJsonIdent:ADD('rBuffer', INT64(rBuffer)) NO-ERROR.
            hBuffer:BUFFER-RELEASE ().
            
            outilitiesHandler:writeLastRecord(
                INPUT oJsonIdent  ,
                INPUT cUniqueWhere
                ).

            lRetVal = TRUE.
            LEAVE.
        END.
        
        IF lRetVal THEN 
        DO:
            IF lWordIndex THEN fillWordIndexTable().
        END.
        //
        //  Datensatz anhand der RECID und den letzten Kriterien in der Tabelle finden und Pagination ermitteln
        //
        DO WHILE lRetVal:
            outilitiesHandler:readLastcWhere(
                INPUT  oJsonIdent,
                INPUT  cFileName ,
                OUTPUT cWhere
                ).
// MESSAGE 'cWhere nach add von Datensatz' cWhere.            
            outilitiesHandler:evaluatePageNumber(
                INPUT-OUTPUT oJsonIdent   ,
                INPUT        cWhere       ,
                INPUT        rBuffer      ,
                INPUT        'current'
                ).            
       
            createTempTable().
            iAnzRec = fillTemptableFromTable(
                OUTPUT oJsonReturn
                ).
                
            CREATE BUFFER hUniqueBuffer FOR TABLE cFileName.
            hUniqueBuffer:FIND-UNIQUE (cUniqueWhere, NO-LOCK) NO-ERROR.
            outilitiesHandler:evaluateErrorStatus(hError).
            hField = hUniqueBuffer:BUFFER-FIELD('language_id'):HANDLE NO-ERROR.
            IF  VALID-HANDLE(hField)   AND
                NOT ERROR-STATUS:ERROR THEN oJsonIdent:SET('language_id', hField:BUFFER-VALUE).

            oselectboxHandler:getVariableSelectBoxes(
                INPUT  oJsonIdent      ,
                OUTPUT oJsonSelectBoxes
                ).
            IF VALID-OBJECT(oJsonSelectBoxes) THEN oJsonReturn:ADD('selectOptions', oJsonSelectBoxes).
            
            lRetVal = TRUE.
            LEAVE.
        END.
        DELETE OBJECT hBuffer       NO-ERROR.
        DELETE OBJECT hUniqueBuffer NO-ERROR.

        IF lRetVal THEN 
        DO:
            oJsonReturn:ADD('success', TRUE     ).
        
            outilitiesHandler:createInfoBox(
                INPUT  oJsonIdent       ,
                INPUT  '2008'           ,
                INPUT  ''               ,
                OUTPUT oJsonMessageBox
                ) NO-ERROR.
            oJsonReturn:ADD('showMessage', oJsonMessageBox).

            RETURN TRUE.
        END.

        IF NOT lRetVal THEN 
        DO:
            oJsonMessage = NEW JsonObject().
            oJsonMessage:ADD('success', FALSE).
            oJsonMessage:ADD('message', lcMessage).
            oJsonMessage:WRITE(lcJsonString, FALSE).
            
            oJsonReturn = oJsonMessage.
            
            RETURN TRUE.
        END.
        
        CATCH e AS Progress.Lang.Error:

        END CATCH.

        FINALLY:

        END FINALLY.

    END METHOD.

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

    METHOD PUBLIC VOID createTempTable(
        ):

        DEFINE VARIABLE ii             AS INTEGER   NO-UNDO.
        DEFINE VARIABLE i1             AS INTEGER   NO-UNDO.
        DEFINE VARIABLE cSerializeName AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cttName        AS CHARACTER NO-UNDO.        
        DEFINE VARIABLE cBoxfields     AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cAddField      AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cField         AS CHARACTER NO-UNDO.
// MESSAGE cCompany '-' cFormId '-' htt::FormId.
        FIND FIRST selectboxfields NO-LOCK 
            WHERE selectboxfields.company    = cCompany
            AND   selectboxfields.user_name  = 'admin'
            AND   selectboxfields.program    = cFormId
            AND   selectboxfields.table_name = 'table' NO-ERROR.
        cBoxfields = ''.
        lBoxFields = FALSE.
        IF AVAILABLE selectboxfields THEN 
        DO:
            cBoxfields = selectboxfields.boxfields.
            cBoxfields = cBoxfields
                + (IF cBoxfields = '' THEN '' ELSE ',')
                + selectboxfields.boxfieldsFix.
            cBoxFields = REPLACE(cBoxfields, ',', ';').
            lBoxFields = TRUE.
// MESSAGE 'Alle Boxfields für' cFormId '->' cBoxfields.
        END. 

        IF VALID-HANDLE(ttTable) THEN DELETE OBJECT ttTable NO-ERROR.
        httTable = ?.
        
        CREATE TEMP-TABLE ttTable.
        ttTable:ADD-FIELDS-FROM (cFileName, 'wordindex').   /*  Alle Felder aus dem Buffer, ausser wordindex    */
        ttTable:ADD-NEW-FIELD ('color', 'character', 0, 'x(20)').
        ttTable:ADD-NEW-FIELD ('fieldColors', 'character', 5, 'x(20)').

        IF lBoxFields THEN  
        DO:
            DO ii = 1 TO NUM-ENTRIES(cBoxFields, ';'):
                cField = ENTRY(ii, cBoxFields, ';').
                i1     = INDEX(cField, '_') + 1.
                cField = SUBSTRING(cField,i1) + '_BoxField'.
                ttTable:ADD-NEW-FIELD (cField, 'character', 0, 'x(100)').
            END.
        END.

        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.
        
        cFunction = htt::FUNCTION NO-ERROR.
        CASE cFunction:
            WHEN 'delete' THEN 
                cttName = 'record'.
            WHEN 'update' THEN 
                cttName = 'record'.
            WHEN 'change' THEN 
                cttName = 'record'.
            WHEN 'create' THEN 
                cttName = 'record'.
            WHEN 'loaddataunique' THEN 
                cttName = 'record'.
            OTHERWISE 
            cttName = 'records'.
        END CASE.
        ttTable:TEMP-TABLE-PREPARE (cttName).
        httTable = ttTable:DEFAULT-BUFFER-HANDLE.
        //
        //  Den Feldnamen wird für das Front-End der Tabellenname vorangestellt (Serialize-Name)
        //
        DO ii = 1 TO httTable:NUM-FIELDS:
            CASE httTable:BUFFER-FIELD(ii):NAME:
                WHEN 'active' THEN 
                    cSerializeName = 'active'.
                WHEN 'color' THEN 
                    cSerializeName = 'color'.
                WHEN 'fieldColors' THEN 
                    cSerializeName = 'fieldColors'.
                OTHERWISE 
                cSerializeName = cFileName + '_' + httTable:BUFFER-FIELD(ii):NAME.
            END CASE.
            httTable:BUFFER-FIELD(ii):SERIALIZE-NAME = cSerializeName NO-ERROR.
// MESSAGE 'NEU ' httTable:BUFFER-FIELD(ii):NAME httTable:BUFFER-FIELD(ii):EXTENT.
        END.

    END METHOD.

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

    METHOD PUBLIC VOID createUniqueWhere(
        INPUT  hBuffer      AS HANDLE,
        OUTPUT cUniqueWhere AS CHARACTER 
        ):
            
        DEFINE VARIABLE hField       AS HANDLE    NO-UNDO.
        DEFINE VARIABLE cIndexFields AS CHARACTER NO-UNDO.
        
        cUniqueWhere  = ''.
        cString       = 'WHERE'.
        FOR EACH ttPrimaryIndex NO-LOCK:
            hField = hBuffer:BUFFER-FIELD(ttPrimaryIndex.cFieldName):HANDLE.    
            CASE ttPrimaryIndex.cDataType:
                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.
            cUniqueWhere = cUniqueWhere + cString
                + SUBSTITUTE(' &1.&2 = &3 ', ttPrimaryIndex.cFileName, ttPrimaryIndex.cFieldName, cValue).
            cString = 'AND'.
        END.
        
        RETURN.

    END METHOD.

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

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

        DEFINE VARIABLE oJsonMessage     AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonMessageBox  AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonRecord      AS JsonObject NO-UNDO.
        DEFINE VARIABLE oMasterKeyFields AS JsonObject NO-UNDO.
        DEFINE VARIABLE oRecords         AS JsonArray  NO-UNDO.
        DEFINE VARIABLE oRecord          AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonSelectBoxes AS JsonObject NO-UNDO.

        DEFINE VARIABLE lRetVal          AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE lOK              AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE hField           AS HANDLE     NO-UNDO.
        DEFINE VARIABLE htField          AS HANDLE     NO-UNDO.
        DEFINE VARIABLE rBuffer          AS RECID      NO-UNDO.
        DEFINE VARIABLE iContact_Id      AS INTEGER    NO-UNDO.
        
        DEFINE VARIABLE lcttTable        AS LONGCHAR   NO-UNDO.
// oJsonData:writefile(SUBSTITUTE('C:\TEMP\delete_jsondata_&1.json', cFileName), TRUE).
        oJsonRecord = NEW JsonObject().
        oJsonRecord = oJsonData:GetJsonObject('record') NO-ERROR.

        oMasterKeyFields = NEW JsonObject().
        oMasterKeyFields = oJsonData:GetJsonObject('masterKeyFields') NO-ERROR.
        
        CREATE BUFFER hBuffer FOR TABLE cFileName.
        createTempTable().
        oJsonRecord:Write(lcttTable, FALSE).
        lOK = ttTable:READ-JSON('longchar', lcttTable, 'EMPTY') NO-ERROR.
        outilitiesHandler:evaluateErrorStatus(hError).
        httTable:FIND-FIRST('', NO-LOCK).
        //
        //  Erzeugen von Where-Statement für UNIQUE-Find
        //
        createUniqueWhere(
            INPUT  httTable,
            OUTPUT cUniqueWhere
            ).

        lRetVal = FALSE.
        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
            lOK = hBuffer:FIND-UNIQUE(cUniqueWhere, NO-LOCK) NO-ERROR.
            IF NOT lOK THEN 
            DO:
                outilitiesHandler:createErrorBox(
                    INPUT  oJsonIdent       ,
                    INPUT  '2000'           ,
                    INPUT  ''               ,
                    OUTPUT oJsonMessageBox
                    ).
                oJsonReturn = NEW JsonObject().
                oJsonReturn:ADD('success'     , FALSE          ).
                oJsonReturn:ADD('showMessage' , oJsonMessageBox).
                RETURN TRUE.
            END.

            rBuffer = hBuffer:RECID.
            hBuffer:BUFFER-RELEASE ().

            cActiveSelection = (IF oJsonIdent:HAS('activeFilter') THEN oJsonIdent:GetCharacter('activeFilter') ELSE '').
            IF cActiveSelection = 'LBL_FILTER_ACTIVE' THEN 
            DO: 
                outilitiesHandler:evaluatePageNumber(
                    INPUT-OUTPUT oJsonIdent   ,
                    INPUT        cWhere       ,
                    INPUT        rBuffer      ,
                    INPUT        'before'
                    ).
            END.
                            
            iStartPage = INTEGER(oJsonIdent:GetCharacter('page'))  NO-ERROR.
            iIndex     = INTEGER(oJsonIdent:GetCharacter('index')) NO-ERROR.

            lOK = hBuffer:FIND-UNIQUE(cUniqueWhere, EXCLUSIVE-LOCK, NO-WAIT) NO-ERROR.
            IF hBuffer:LOCKED THEN 
            DO:
                hBuffer:FIND-UNIQUE(cUniqueWhere, NO-LOCK) NO-ERROR.
                rBuffer = hBuffer:RECID. 
                outilitiesHandler:createLockMessage(
                    INPUT  oJsonIdent,
                    INPUT  rBuffer  ,
                    OUTPUT oJsonMessageBox
                    ).
                oJsonReturn = NEW JsonObject().
                oJsonReturn:ADD('success'     , FALSE          ).
                oJsonReturn:ADD('showMessage', oJsonMessageBox).
                RETURN TRUE.
            END.
                
            DO WHILE lActive :
                hField = hBuffer:BUFFER-FIELD('active'):HANDLE NO-ERROR.
                IF  ERROR-STATUS:ERROR        OR
                    NOT VALID-HANDLE(hField) THEN LEAVE.
                hField:BUFFER-VALUE = FALSE NO-ERROR.

                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('updated_by'):HANDLE NO-ERROR.
                IF  NOT ERROR-STATUS:ERROR AND
                    VALID-HANDLE(hField)   THEN hField:BUFFER-VALUE = oJsonIdent:GetCharacter('H_display_name').

                httTable:BUFFER-COPY(hBuffer).
                
                hBuffer:BUFFER-RELEASE ().

                lRetVal = TRUE.
                LEAVE.                
            END.
            
            DO WHILE NOT lRetVal:
                lRetVal = hBuffer:BUFFER-DELETE ().
                hBuffer:BUFFER-RELEASE ().
                
                LEAVE.
            END.
            
            IF lActive THEN fillWordIndexTable().
            //
            //  Letzte Abfrage wiederholen und Temp-Tabelle füllen
            //
            outilitiesHandler:readLastcWhere(
                INPUT  oJsonIdent,
                INPUT  cFileName,
                OUTPUT cWhere
                ) NO-ERROR.
            outilitiesHandler:evaluateErrorStatus(hError).
// MESSAGE 'cWhere nach Löschung ' cWhere.
            createTempTable().

            fillTemptableFromTable(
                OUTPUT oJsonReturn
                ).
 
            oRecords = NEW JsonArray().
            oRecords = oJsonReturn:GetJsonArray('records').
            oRecord  = NEW JsonObject().
            oRecord  = (IF iIndex = oRecords:LENGTH THEN oRecords:GetJsonObject(iIndex) ELSE oRecords:GetJsonObject(iIndex + 1) ). 
            
            oselectboxHandler:getVariableSelectBoxes(
                INPUT  oJsonIdent,
                OUTPUT oJsonSelectBoxes
                ).
            IF VALID-OBJECT(oJsonSelectBoxes) THEN oJsonReturn:ADD('selectOptions', oJsonSelectBoxes).
            
            LEAVE.
        END.

        IF lRetVal THEN 
        DO:             
            oJsonReturn:ADD('success', 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:
            DELETE OBJECT oJsonArray    NO-ERROR.
            DELETE OBJECT oJsonData     NO-ERROR.
        END FINALLY.

    END METHOD.

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

    METHOD PUBLIC INTEGER fillTemptableFromTable(
        OUTPUT oJsonReturn  AS JsonObject 
        ):
        
        DEFINE VARIABLE iRetVal       AS INTEGER    NO-UNDO INIT -1.
        DEFINE VARIABLE i1            AS INTEGER    NO-UNDO.
        DEFINE VARIABLE hQuery        AS HANDLE     NO-UNDO.
        DEFINE VARIABLE hBuffer       AS HANDLE     NO-UNDO.
        DEFINE VARIABLE iTotalRecords AS INTEGER    NO-UNDO.
        DEFINE VARIABLE cAddress      AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE hField        AS HANDLE     NO-UNDO.
        DEFINE VARIABLE rBuffer       AS RECID      NO-UNDO.
        DEFINE VARIABLE lFound        AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE cField        AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cFieldValue   AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cPreWhere     AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE rBefore       AS RECID      NO-UNDO.
        
        DEFINE VARIABLE oRecords      AS JsonArray  NO-UNDO.
        DEFINE VARIABLE oInfoRecord   AS JsonObject NO-UNDO.
        
        iStartPage  = 1.
        iMaxRecords = 25.
        iIndex      = 0.
        rBuffer     = (IF oJsonIdent:HAS('rBuffer') THEN oJsonIdent:GetInt64('rBuffer') ELSE ?).
        //
        //  Manchmal kommen die Werte als Integer, manchmal als character
        //
        IF oJsonIdent:HAS('limit') THEN 
        DO:
            iMaxRecords = (IF oJsonIdent:getType('limit') = 1 THEN INTEGER(oJsonIdent:GetCharacter('limit')) ELSE oJsonIdent:GetInteger('limit')).
        END. 
        IF oJsonIdent:HAS('page')  THEN 
        DO:
            iStartPage = (IF oJsonIdent:getType('page')   = 1 THEN INTEGER(oJsonIdent:GetCharacter('page')) ELSE oJsonIdent:GetInteger('page')).
        END. 
        IF oJsonIdent:HAS('index') THEN 
        DO:
            iIndex     = (IF oJsonIdent:getType('index')  = 1 THEN INTEGER(oJsonIdent:GetCharacter('index')) ELSE oJsonIdent:GetInteger('index')).
        END.
        iStartRecord = ((iStartPage - 1) * iMaxRecords) + 1.
        //
        //  Für das Dynamische Query wird PRESELECT verwendet für die Pagination
        //
// MESSAGE '-> MaxRecords =' iMaxRecords SKIP 'Startpage =' iStartPage SKIP 'Index =' iIndex SKIP 'Startrecord =' iStartRecord.
// MESSAGE 'cWhere in fillTempTable =' cFileName '->' cWhere.
        cPreWhere = SUBSTITUTE(' PRESELECT EACH &1 &2 NO-LOCK ', cFileName, cWhere) NO-ERROR.
// MESSAGE 'cPreWhere in fillTempTable =' cPreWhere.
        CREATE QUERY hQuery.
        
        CREATE BUFFER hBuffer FOR TABLE cFileName.
        hQuery:SET-BUFFERS (hBuffer) NO-ERROR.
        outilitiesHandler:evaluateErrorStatus(hError).

        hQuery:QUERY-PREPARE (cPreWhere) NO-ERROR.
        outilitiesHandler:evaluateErrorStatus(hError).

        hQuery:QUERY-OPEN ().

        iTotalRecords = hQuery:NUM-RESULTS.
        hQuery:REPOSITION-FORWARD(iStartRecord - 1) NO-ERROR.
        hQuery:GET-NEXT ().
        iCurrentPosition = 0.
        iAnzahlRecords   = 0.
// MESSAGE 'Start query mit StartRecord ' iStartRecord 'und cWhere ' cPreWhere.
        ttTable:EMPTY-TEMP-TABLE ().
        DO WHILE NOT hQuery:QUERY-OFF-END:
            IF iCurrentPosition = 0 THEN iCurrentPosition = iStartRecord.
            iAnzahlRecords = iAnzahlRecords + 1.
            httTable:BUFFER-CREATE().
            httTable:BUFFER-COPY(hBuffer).
            
/*            IF cFileName = 'users' AND hBuffer::ROLE BEGINS 'admin' THEN                               */
/*                ASSIGN                                                                                 */
/*                                                                                                       */
/*                    httTable:BUFFER-FIELD ('color'):BUFFER-VALUE()        = 'green'                    */
/*                    httTable:BUFFER-FIELD ('fieldColors'):BUFFER-VALUE(1) = "'users_firstname':'blue'".*/

            rBefore = hBuffer:RECID.             
            IF rBuffer <> ? AND hBuffer:RECID = rBuffer THEN iIndex = iAnzahlRecords - 1.
            IF iAnzahlRecords >= iMaxRecords THEN LEAVE.
            hQuery:GET-NEXT ().
        END.
        hQuery:QUERY-CLOSE ().
        DELETE OBJECT hQuery  NO-ERROR.
        DELETE OBJECT hBuffer NO-ERROR.

        IF lBoxFields THEN 
        DO:
            lFound = FALSE.
            CREATE QUERY hQuery.
            hQuery:SET-BUFFERS(httTable).
            hQuery:QUERY-PREPARE (SUBSTITUTE('FOR EACH &1', httTable:NAME )).
            hQuery:QUERY-OPEN ().
            hQuery:GET-FIRST () NO-ERROR.

            DO WHILE NOT hQuery:QUERY-OFF-END:
                DO i1 = 1 TO httTable:NUM-FIELDS:
                    IF INDEX(httTable:BUFFER-FIELD(i1):NAME, 'BoxField') = 0 THEN NEXT.
                    lFound      = TRUE.
                    cField      = httTable:BUFFER-FIELD(i1):NAME.
                    cField      = REPLACE(cField, '_BoxField', '').
                    hField      = httTable:BUFFER-FIELD(cField):HANDLE NO-ERROR.
                    IF ERROR-STATUS:ERROR       THEN NEXT.
                    IF NOT VALID-HANDLE(hField) THEN NEXT.
                    cFieldValue = hField:BUFFER-VALUE.

                    httTable:BUFFER-FIELD(i1):BUFFER-VALUE =
                        outilitiesHandler:getBoxFieldText(
                        INPUT oJsonIdent ,
                        INPUT cField     ,
                        INPUT cFieldValue
                        ) NO-ERROR. 

                END.
                IF lFound = FALSE THEN LEAVE. 
                hQuery:GET-NEXT () NO-ERROR.
            END.
            hQuery:QUERY-CLOSE ().
            DELETE OBJECT hQuery  NO-ERROR.
        END.


        oRecords = NEW JsonArray().
        httTable:WRITE-JSON('JsonArray', oRecords).
// MESSAGE 'ttTable gefüllt ' iANzahlRecords.
// oRecords:WriteFile(SUBSTITUTE('C:\TEMP\fillTempTable_&1_records.json', htt::FormId), TRUE).
        
        iPageCounter = iTotalRecords / iMaxRecords.
        IF (iPageCounter * iMaxRecords) < iTotalRecords THEN iPageCounter = iPageCounter + 1.  

        oJsonReturn = NEW JsonObject().
        oJsonReturn:ADD('records'     , oRecords      ).
        oJsonReturn:ADD('currentPage' , iStartPage    ).
        oJsonReturn:ADD('maxRecords'  , iTotalRecords ).
        oJsonReturn:ADD('pageCount'   , iPageCounter  ).
        oJsonReturn:ADD('recordCount' , iAnzahlRecords).
        oJsonReturn:ADD('currentIndex', iIndex        ).
        
        IF  iAnzahlRecords > 0 AND
            rBuffer        = ? THEN 
        DO:
            httTable:FIND-FIRST('', NO-LOCK) NO-ERROR.
            createUniqueWhere(
                INPUT  httTable    ,
                OUTPUT cUniqueWhere
                ).
// MESSAGE 'writeLastRecord ' cUniqueWhere.
            outilitiesHandler:writeLastRecord(
                INPUT oJsonIdent,
                INPUT cUniqueWhere
                ). 
        END.
        
        iRetVal = iAnzahlRecords.
// oJsonReturn:WriteFile(SUBSTITUTE('C:\TEMP\fillTempTable_return_&1.json', cFormId), TRUE).        
// MESSAGE 'ende filltable'.
        RETURN iRetVal.

    END METHOD.

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

    METHOD PUBLIC VOID fillWordIndexTable(
        ):
            
        DEFINE VARIABLE i1        AS INTEGER   NO-UNDO.
        DEFINE VARIABLE hwibuffer AS HANDLE    NO-UNDO.
        DEFINE VARIABLE hField    AS HANDLE    NO-UNDO.
        DEFINE VARIABLE cValue    AS CHARACTER NO-UNDO.
        
        EMPTY TEMP-TABLE ttWordIndexTable.
        MESSAGE 'Filename =' cFileName.
        CREATE BUFFER hwibuffer FOR TABLE cFileName.
        hwibuffer:FIND-UNIQUE (cUniqueWhere, NO-LOCK).
        
        DO i1 = 1 TO hwibuffer:NUM-FIELDS:
            hField = hwibuffer:BUFFER-FIELD(i1):HANDLE NO-ERROR.
            IF INDEX(hField:NAME, 'SHA')      > 0  THEN NEXT.
            IF INDEX(hField:NAME, 'word')     > 0  THEN NEXT.
            IF INDEX(hField:NAME, 'updated_') > 0  THEN NEXT.
            IF INDEX(hField:NAME, 'created_') > 0  THEN NEXT.
            IF INDEX(hField:NAME, '_display') > 0  THEN NEXT.
            IF hField:EXTENT > 0                   THEN NEXT.
            IF hField:DATA-TYPE = 'logical'        THEN NEXT.
            
            cValue = hField:BUFFER-VALUE NO-ERROR.
            IF cValue = ? THEN NEXT.
            
            IF  hField:NAME BEGINS 'phone'  OR
                hField:NAME BEGINS 'mobile' OR
                hField:NAME BEGINS 'Fax'    THEN
            DO:
                cValue = hField:BUFFER-VALUE.
                cValue = REPLACE(cValue, ' ', '').
                cValue = REPLACE(cValue, '.', '').
                cValue = REPLACE(cValue, "'", '').
                cValue = REPLACE(cValue, '-', '').
            END.
            CREATE  ttWordIndexTable.
            ASSIGN
                ttWordIndexTable.cFileName  = hwibuffer:NAME 
                ttWordIndexTable.cFieldName = hField:NAME 
                ttWordIndexTable.cDataType  = hField:DATA-TYPE
                ttWordIndexTable.cValue     = cValue
                .
        END.
        
        DELETE OBJECT hwibuffer NO-ERROR.
        
        hwibuffer = ?.
        hwibuffer = TEMP-TABLE ttWordIndexTable:DEFAULT-BUFFER-HANDLE.
        cValue    = outilitiesHandler:createWordindexFromTable(
            INPUT hwibuffer
            ).

        MESSAGE cFileName '-' cUniqueWhere '- wordIndex ' cValue.            
        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
            CREATE BUFFER hwiBuffer FOR TABLE cFileName.
            hwiBuffer:FIND-UNIQUE (cUniqueWhere, EXCLUSIVE-LOCK).
            hwibuffer::wordIndex = cValue.
            hwibuffer:BUFFER-RELEASE ().
            LEAVE.
        END.
            
        RETURN.

    END METHOD.

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

    METHOD PUBLIC LOGICAL getChanges(
        INPUT  oJsonIdent  AS JsonObject,
        OUTPUT oJsonResult AS JsonObject
        ):
            
        DEFINE VARIABLE oJsonMessage    AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonMessageBox 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 hField          AS HANDLE     NO-UNDO.
        DEFINE VARIABLE htField         AS HANDLE     NO-UNDO.
        DEFINE VARIABLE cField          AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cBufferField    AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cValue          AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE iValue          AS INTEGER    NO-UNDO.
        DEFINE VARIABLE lValue          AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE cWordIndex      AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE rBuffer         AS RECID      NO-UNDO.
        DEFINE VARIABLE cFieldNames     AS CHARACTER  NO-UNDO EXTENT.
        DEFINE VARIABLE cReplace        AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE lNew            AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE iType           AS INTEGER    NO-UNDO.
        
        DEFINE VARIABLE cFunction       AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cChangeAction   AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cUniqueWhere    AS CHARACTER  NO-UNDO.

        DEFINE VARIABLE oJsonReturn     AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonRecord     AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonArray      AS JsonArray  NO-UNDO.
        DEFINE VARIABLE oJsonAction     AS JsonArray  NO-UNDO.
        
        outilitiesHandler = NEW utilitiesHandler().
        
        httKeyFields    = TEMP-TABLE ttKeyFields   :DEFAULT-BUFFER-HANDLE.
        httPrimaryIndex = TEMP-TABLE ttPrimaryIndex:DEFAULT-BUFFER-HANDLE.
        //
        //  Ermitteln des Tabellennamens, ob die Tabelle das Feld "company" und/oder das Feld "active" enthält
        //
        MESSAGE 'getChanges'.
        outilitiesHandler:evaluateFile(
            INPUT-OUTPUT oJsonIdent     ,
            OUTPUT       cFileName      ,
            OUTPUT       lCompany       ,
            OUTPUT       lActive        ,
            OUTPUT       lWordIndex     ,
            INPUT-OUTPUT httKeyFields   ,
            INPUT-OUTPUT httPrimaryIndex
            ).
            
        cFunction = oJsonIdent:GetCharacter('function').
        CREATE BUFFER hBuffer FOR TABLE cFileName.

        createTempTable().

        httTable:BUFFER-CREATE().
        cReplace    = SUBSTITUTE('&1_', cFileName).            
        cFieldNames = oJsonIdent:GetNames().
        
        DO ii = 1 TO EXTENT(cFieldNames):
            cField       = cFieldNames[ii].
            IF NOT cField BEGINS cFileName THEN NEXT.
            cBufferField = REPLACE(cField, cReplace, '').
            cValue       = oJsonIdent:GetCharacter(cField).
            hField       = httTable:BUFFER-FIELD(cBufferField):HANDLE NO-ERROR.
            IF ERROR-STATUS:ERROR        THEN NEXT.
            IF NOT VALID-HANDLE (hField) THEN NEXT.
            IF hField:DATA-TYPE = 'date' THEN cValue = outilitiesHandler:iso2date(INPUT cValue). 
 
            iType = oJsonRecord:getType(cField). 
            CASE iType:
                WHEN 2 THEN 
                    DO:
                        iValue = oJsonRecord:GetInteger(cField).
                        hField:BUFFER-VALUE = iValue NO-ERROR.
                    END.
                WHEN 3 THEN 
                    DO:
                        lValue = oJsonRecord:GetLogical(cField).
                        hField:BUFFER-VALUE = lValue NO-ERROR.
                    END.
                OTHERWISE 
                DO:
                    cValue = oJsonRecord:GetCharacter(cField).
                    IF hField:DATA-TYPE = 'character' THEN hField:BUFFER-VALUE = cValue NO-ERROR.
                    IF hField:DATA-TYPE = 'date'      THEN hField:BUFFER-VALUE = DATE(outilitiesHandler:iso2date(cValue)).
                END.
            END CASE.
            lOk = outilitiesHandler:evaluateErrorStatus(hError).
            IF lOk THEN NEXT.
        END.
// httTable:WRITE-JSON ('FILE', 'C:\TEMP\ttTable_Inhalt.json', TRUE).
        //
        //  Erzeugen von Where-Statement für UNIQUE-Find
        //
        httTable:FIND-FIRST('', NO-LOCK) NO-ERROR.
        createUniqueWhere(
            INPUT  httTable,
            OUTPUT cWhere
            ).
        cUniqueWhere = cWhere.
        
        lOK = hBuffer:FIND-UNIQUE(cWhere, NO-LOCK) NO-ERROR.
        IF NOT lOK THEN lNew = TRUE.
        
        oJsonReturn = NEW JsonObject().
        oJsonReturn:ADD('success', TRUE).
        
        cChangeAction = oJsonIdent:GetCharacter('changeAction').
// MESSAGE 'ChangeAction =' cChangeAction.
        CASE cChangeAction:
        /*            WHEN 'changeFixedAddress' THEN                                             */
        /*                DO:                                                                    */
        /*                    lAddressFix = LOGICAL(oJsonIdent:GetCharacter('changedValue')).    */
        /*// MESSAGE httTable::ADDress_fix '-' oJsonIdent:GetCharacter('changedValue').          */
        /*                    oJsonAction = NEW JsonArray().                                     */
        /*                    oJsonAction:ADD('addresses_address').                              */
        /*                    IF lAddressFix THEN oJsonReturn:ADD('editableFields', oJsonAction).*/
        /*                    ELSE                oJsonReturn:ADD('disabledFields', oJsonAction).*/
        /*                    httTable::Address_fix = oJsonIdent:GetCharacter('changedValue').   */
        /*                END.                                                                   */
        END CASE. 
        
        oJsonRecord = NEW JsonObject().
        oJsonArray  = NEW JsonArray ().

        httTable:WRITE-JSON('JsonObject', oJsonRecord).
        oJsonArray  = oJsonRecord:GetJsonArray('record').
        oJsonRecord = oJsonArray:GetJsonObject(1). 
        oJsonReturn:ADD('record', oJsonRecord).
        
        oJsonResult = oJsonReturn.
        
        lRetVal = TRUE.
        RETURN lRetVal.
            
    END METHOD.

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

    METHOD PUBLIC LOGICAL getData(
        OUTPUT oJsonReturn AS JsonObject  
        ):
        
        DEFINE VARIABLE ii               AS INTEGER    NO-UNDO.
        DEFINE VARIABLE i1               AS INTEGER    NO-UNDO.
        DEFINE VARIABLE iAnzRec          AS INTEGER    NO-UNDO.
        DEFINE VARIABLE lRetVal          AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE iRetVal          AS INTEGER    NO-UNDO.
        DEFINE VARIABLE lOK              AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE cAddress         AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE hFeld            AS HANDLE     NO-UNDO.
        DEFINE VARIABLE cFormUser        AS CHARACTER  NO-UNDO.
        
        DEFINE VARIABLE oRecords         AS JsonArray  NO-UNDO.
        DEFINE VARIABLE oJsonEditable    AS JsonArray  NO-UNDO.
        DEFINE VARIABLE oJsonBox         AS JsonArray  NO-UNDO.
        DEFINE VARIABLE oJsonSelectBoxes AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonMessageBox  AS JsonObject NO-UNDO.
        DEFINE VARIABLE oInfoRecord      AS JsonObject NO-UNDO.

        iIndex = 0.        
        buildWhere().
        MESSAGE 'cWhere nach buildwhere in getdata' cWhere.
        ii      = 0.
        iAnzRec = 0.
        ttTable:EMPTY-TEMP-TABLE ().
        CREATE QUERY hQuery.
//        cWhere = SUBSTITUTE('FOR EACH &1 NO-LOCK &2 ', cFileName, cWhere) NO-ERROR.
// MESSAGE 'cWhere loaddate for ' cFileName '->' cWhere.
        oJsonIdent:WriteFile('C:\TEMP\getData_oJsonIdent.json', TRUE ).
        /*        IF NOT oJsonIdent:HAS('search') THEN  */
        /*        DO:                                   */
        /*            outilitiesHandler:writeLastcWhere(*/
        /*                INPUT  oJsonIdent ,           */
        /*                INPUT  cFileName  ,           */
        /*                INPUT  cWhere                 */
        /*                ).                            */
        /*        END.                                  */
        //
        //  Für das Dynamische Query wird PRESELECT verwendet für die Pagination
        //
        iRetVal = fillTemptableFromTable(
            OUTPUT oJsonReturn
            ).
            
        IF iRetVal <= 0 THEN 
        DO:
            outilitiesHandler:createInfoBox(
                INPUT  oJsonIdent   ,
                INPUT  '2009'       ,
                INPUT  ''           ,
                OUTPUT oJsonMessageBox
                ).
            oJsonReturn:ADD('success', (IF iRetVal < 0 THEN FALSE ELSE TRUE)).
            oJsonReturn:ADD('showMessage', oJsonMessageBox).
// oJsonReturn:WriteFile('C:\TEMP\getData_nullRecords_return.json', TRUE).            
            RETURN lRetVal.
        END.

        lRetVal = httTable:FIND-FIRST('', NO-LOCK).
        hFeld   = httTable:BUFFER-FIELD('language_id'):HANDLE NO-ERROR.
        IF  VALID-HANDLE(hFeld)   AND
            NOT ERROR-STATUS:ERROR THEN oJsonIdent:SET('language_id', hFeld:BUFFER-VALUE).

        oselectboxHandler:getVariableSelectBoxes(
            INPUT  oJsonIdent      ,
            OUTPUT oJsonSelectBoxes
            ).
        IF VALID-OBJECT(oJsonSelectBoxes) THEN oJsonReturn:ADD('selectOptions', oJsonSelectBoxes).

        outilitiesHandler:writePosition(
            INPUT  oJsonIdent       ,
            INPUT  cFileName        ,
            INPUT  iCurrentPosition ,
            INPUT  iStartPage       ,
            INPUT  iMaxRecords
            ).
// oJsonReturn:WriteFile('C:\TEMP\addresses_getData_messages.json', TRUE).
        
        lRetVal = TRUE.        
        RETURN lRetVal.

    END METHOD.

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

    METHOD PUBLIC LOGICAL getDataUnique(
        OUTPUT oJsonReturn  AS JsonObject
        ):
            
        DEFINE VARIABLE lOK              AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE cUniqueWhere     AS CHARACTER  NO-UNDO.
            
        DEFINE VARIABLE hField           AS HANDLE     NO-UNDO.
        
        DEFINE VARIABLE oJsonRecord      AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonSelectBoxes AS JsonObject NO-UNDO.
        DEFINE VARIABLE oInfoRecord      AS JsonObject NO-UNDO.
        
        CREATE BUFFER hBuffer FOR TABLE cFileName.
        createTempTable().
        MESSAGE cFileName.
        outilitiesHandler:readLastRecord(
            INPUT  oJsonIdent   ,
            OUTPUT cUniqueWhere
            ).
        lOk = hBuffer:FIND-UNIQUE (cUniqueWhere, NO-LOCK) NO-ERROR.
        httTable:BUFFER-CREATE ().
        httTable:BUFFER-COPY(hBuffer). 
        httTable:FIND-FIRST('', NO-LOCK) NO-ERROR.

        oJsonReturn = NEW JsonObject().
        oJsonData   = NEW JsonObject().
        oJsonRecord = NEW JsonObject().
        oJsonArray  = NEW JsonArray ().
        //
        //  den ersten Datensatz in der TEMP-TABLE lesen
        //
        hField = httTable:BUFFER-FIELD('language_id'):HANDLE NO-ERROR.
        IF  VALID-HANDLE(hField)   AND
            NOT ERROR-STATUS:ERROR THEN oJsonIdent:SET('language_id', httTable::language_id).
            
        httTable:WRITE-JSON('JsonObject', oJsonData).
        oJsonArray  = oJsonData:GetJsonArray('record').
        oJsonRecord = oJsonArray:GetJsonObject(1).

        oselectboxHandler:getVariableSelectBoxes(
            INPUT  oJsonIdent      ,
            OUTPUT oJsonSelectBoxes
            ).
            
        lOk = TRUE.    
        oJsonReturn = NEW JsonObject().
        oJsonReturn:ADD('success', lOK        ).
        oJsonReturn:ADD('record' , oJsonRecord).
        IF VALID-OBJECT(oInfoRecord)      THEN oJsonReturn:ADD('infoRecord'   , oInfoRecord     ).
        IF VALID-OBJECT(oJsonSelectBoxes) THEN oJsonReturn:ADD('selectOptions', oJsonSelectBoxes).
        
        
        DELETE OBJECT oJsonArray NO-ERROR.
        DELETE OBJECT hBuffer    NO-ERROR.
        DELETE OBJECT ttTable    NO-ERROR.
        
        RETURN lOK.

    END METHOD.

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

    METHOD PUBLIC LOGICAL rebuildData(
        OUTPUT oJsonReturn AS JsonObject  
        ):
        
        DEFINE VARIABLE iAnzRec          AS INTEGER    NO-UNDO.
        DEFINE VARIABLE lRetVal          AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE iRetVal          AS INTEGER    NO-UNDO.
        DEFINE VARIABLE lOK              AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE cAddress         AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE hFeld            AS HANDLE     NO-UNDO.
        DEFINE VARIABLE cFormUser        AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE hUniqueBuffer    AS HANDLE     NO-UNDO.
        DEFINE VARIABLE rBuffer          AS RECID      NO-UNDO.
        
        DEFINE VARIABLE oRecords         AS JsonArray  NO-UNDO.
        DEFINE VARIABLE oJsonEditable    AS JsonArray  NO-UNDO.
        DEFINE VARIABLE oJsonBox         AS JsonArray  NO-UNDO.
        DEFINE VARIABLE oJsonSelectBoxes AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonMessageBox  AS JsonObject NO-UNDO.
        DEFINE VARIABLE oInfoRecord      AS JsonObject NO-UNDO.

        outilitiesHandler:readLastRecord(
            INPUT  oJsonIdent ,
            OUTPUT cUniqueWhere
            ).

        CREATE BUFFER hUniqueBuffer FOR TABLE cFileName.
        hUniqueBuffer:FIND-UNIQUE (cUniqueWhere, NO-LOCK).
        rBuffer = hUniqueBuffer:RECID.
        oJsonIdent:ADD('rBuffer', INT64(rBuffer)).

        IF oJsonIdent:HAS('search') THEN 
        DO:
            oJsonIdent:Remove('search') NO-ERROR.
            oJsonIdent:SET('lSearch', FALSE) NO-ERROR.
        END.

        buildWhere().
        MESSAGE 'cWhere nach buildwhere in rebuilddate' cWhere.
        outilitiesHandler:evaluatePageNumber(
            INPUT-OUTPUT oJsonIdent   ,
            INPUT        cWhere       ,
            INPUT        rBuffer      ,
            INPUT        'current'
            ).            
        MESSAGE 'cWhere bei Rebuild' cWhere.
        // createTempTable().
        iAnzRec = fillTemptableFromTable(
            OUTPUT oJsonReturn
            ).
            
        /*        hUniqueBuffer:FIND-UNIQUE (cUniqueWhere, NO-LOCK) NO-ERROR.*/
        /*        outilitiesHandler:evaluateErrorStatus(hError).*/
        oJsonIdent:SET('language_id', hUniqueBuffer::language_id).
        oselectboxHandler:getVariableSelectBoxes(
            INPUT  oJsonIdent      ,
            OUTPUT oJsonSelectBoxes
            ).
        IF VALID-OBJECT(oJsonSelectBoxes) THEN oJsonReturn:ADD('selectOptions', oJsonSelectBoxes).

        lRetVal = TRUE.
        RETURN lRetVal.

    END METHOD.

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

    METHOD PUBLIC LOGICAL recordChange(
        INPUT  oJsonData    AS JsonObject   ,
        OUTPUT oJsonReturn  AS JsonObject
        ):
            
        DEFINE VARIABLE cReplace         AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cField           AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cBufferField     AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cValue           AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE ii               AS INTEGER    NO-UNDO.
        DEFINE VARIABLE lOK              AS LOGICAL    NO-UNDO.
            
        DEFINE VARIABLE hField           AS HANDLE     NO-UNDO.
        // DEFINE VARIABLE hUniqueBuffer    AS HANDLE     NO-UNDO.
        
        DEFINE VARIABLE oJsonRecord      AS JsonObject NO-UNDO.
        DEFINE VARIABLE oInfoRecord      AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonBox         AS JsonArray  NO-UNDO.
        DEFINE VARIABLE oJsonSelectBoxes AS JsonObject NO-UNDO.
        
        CREATE BUFFER hBuffer FOR TABLE cFileName.
        createTempTable().

        oJsonRecord = NEW JsonObject().
        oJsonRecord = oJsonData:GetJsonObject('record').
// oJsonRecord:WriteFile('C:\Temp\RecordChange_record.json', TRUE).
        httTable:READ-JSON('JsonObject', oJsonRecord) NO-ERROR.
        outilitiesHandler:evaluateErrorStatus(hError).
        //
        //  den ersten Datensatz in der TEMP-TABLE lesen
        //
        httTable:FIND-FIRST('', NO-LOCK) NO-ERROR.
        hField = httTable:BUFFER-FIELD('language_id'):HANDLE NO-ERROR.
        IF  VALID-HANDLE(hField)   AND
            NOT ERROR-STATUS:ERROR THEN oJsonIdent:SET('language_id', httTable::language_id).
        //
        //  Erzeugen von Where-Statement für UNIQUE-Find
        //
        createUniqueWhere(
            INPUT  httTable,
            OUTPUT cUniqueWhere
            ).

        outilitiesHandler:writeLastRecord(
            INPUT  oJsonIdent   ,
            INPUT  cUniqueWhere       
            ).            

        hBuffer:FIND-UNIQUE (cUniqueWhere, NO-LOCK).
        httTable:EMPTY-TEMP-TABLE ().
        httTable:BUFFER-CREATE ().
        httTable:BUFFER-COPY (hBuffer).
        
        DELETE OBJECT oJsonRecord.
        oJsonRecord = NEW JsonObject().
        oJsonArray  = NEW JsonArray().
        httTable:WRITE-JSON('JsonObject', oJsonRecord).
        oJsonArray  = oJsonRecord:GetJsonArray('record').
        oJsonRecord = oJsonArray:GetJsonObject(1).

        oselectboxHandler:getVariableSelectBoxes(
            INPUT  oJsonIdent      ,
            OUTPUT oJsonSelectBoxes
            ).
        lOk = TRUE.    
        oJsonReturn = NEW JsonObject().
        oJsonReturn:ADD('success', lOK        ).
        oJsonReturn:ADD('record' , oJsonRecord).
        IF VALID-OBJECT(oInfoRecord)      THEN oJsonReturn:ADD('infoRecord',    oInfoRecord     ).
        IF VALID-OBJECT(oJsonSelectBoxes) THEN oJsonReturn:ADD('selectOptions', oJsonSelectBoxes).
        
// oJsonReturn:WriteFile(SUBSTITUTE('C:\Temp\RecordChange_&1_return.json', cFileName), TRUE).

        DELETE OBJECT ttTable       NO-ERROR.
        DELETE OBJECT hBuffer       NO-ERROR.
        DELETE OBJECT oJsonArray    NO-ERROR.
        
        RETURN lOK.

    END METHOD.

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

    METHOD PUBLIC LOGICAL updateBegin(
        INPUT  oJsonData     AS JsonObject   ,
        OUTPUT oJsonReturn   AS JsonObject
        ):

        DEFINE VARIABLE lRetVal     AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE lAddressFix AS LOGICAL    NO-UNDO.
        
        DEFINE VARIABLE oJsonAction AS JsonArray  NO-UNDO.
        DEFINE VARIABLE oJsonRecord AS JsonObject NO-UNDO.
        
        iFormTabIndex = (IF oJsonIdent:HAS('formTabIndex') THEN INTEGER(oJsonIdent:GetCharacter('formTabIndex')) ELSE 1).
        
        cFileName   = oJsonIdent:GetCharacter('file_name').
        oJsonRecord = NEW JsonObject().
        oJsonRecord = oJsonData:GetJsonObject('record').
        
        oJsonReturn = NEW JsonObject().
        oJsonReturn:ADD('success', TRUE).
        oJsonReturn:ADD('record', oJsonRecord).

        oJsonAction = NEW JsonArray().
        FOR EACH ttPrimaryIndex NO-LOCK:
            oJsonAction:ADD(SUBSTITUTE('&1_&2', cFileName, ttPrimaryIndex.cFieldName)).
        END.
        oJsonReturn:ADD('disabledFields', oJsonAction).
        
        lRetVal = TRUE.
        RETURN lRetVal.

    END METHOD.

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

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

        DEFINE VARIABLE lRetVal          AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE lOK              AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE hField           AS HANDLE     NO-UNDO.
        DEFINE VARIABLE htField          AS HANDLE     NO-UNDO.
        DEFINE VARIABLE rBuffer          AS RECID      NO-UNDO.
        DEFINE VARIABLE iContact_Id      AS INTEGER    NO-UNDO.
        
        DEFINE VARIABLE lcttTable        AS LONGCHAR   NO-UNDO.

        oJsonRecord = NEW JsonObject().
        oJsonRecord = oJsonData:GetJsonObject('record') NO-ERROR.
// oJsonRecord:WriteFile('C:\TEMP\createAnschrift_record.json', TRUE).
        oMasterKeyFields = NEW JsonObject().
        oMasterKeyFields = oJsonData:GetJsonObject('masterKeyFields') NO-ERROR.
        
        CREATE BUFFER hBuffer FOR TABLE cFileName.
        createTempTable().
        oJsonRecord:Write(lcttTable, FALSE).
// MESSAGE STRING(lcttTable).
        lOK = ttTable:READ-JSON('longchar', lcttTable, 'EMPTY') NO-ERROR.
        outilitiesHandler:evaluateErrorStatus(hError).
        httTable:FIND-FIRST('', NO-LOCK).
// MESSAGE 'e'.
        //
        //  Erzeugen von Where-Statement für UNIQUE-Find
        //
        createUniqueWhere(
            INPUT  httTable,
            OUTPUT cUniqueWhere
            ).
// MESSAGE cUniqueWhere.
        lRetVal = FALSE.
        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
            lOK = hBuffer:FIND-UNIQUE(cUniqueWhere, EXCLUSIVE-LOCK, NO-WAIT) NO-ERROR.
            IF hBuffer:LOCKED THEN 
            DO:
                hBuffer:FIND-UNIQUE(cUniqueWhere, NO-LOCK) NO-ERROR.
                rBuffer = hBuffer:RECID. 
                outilitiesHandler:createLockMessage(
                    INPUT  oJsonIdent,
                    INPUT  rBuffer  ,
                    OUTPUT oJsonMessageBox
                    ).
                oJsonReturn = NEW JsonObject().
                oJsonReturn:ADD('success'     , TRUE          ).
                oJsonReturn:ADD('showMessage', oJsonMessageBox).
                RETURN TRUE.
            END.
            IF NOT lOK THEN 
            DO:
                outilitiesHandler:createErrorBox(
                    INPUT  oJsonIdent       ,
                    INPUT  '2000'           ,
                    INPUT  ''               ,
                    OUTPUT oJsonMessageBox
                    ).
                oJsonReturn = NEW JsonObject().
                oJsonReturn:ADD('success'     , TRUE           ).
                oJsonReturn:ADD('showMessage' , oJsonMessageBox).
                RETURN TRUE.
            END.
            
            rBuffer = hBuffer:RECID.
            DO WHILE lActive :
                hField = hBuffer:BUFFER-FIELD('active') NO-ERROR.
                IF NOT VALID-HANDLE(hField) THEN LEAVE.
                IF hField:BUFFER-VALUE = TRUE THEN LEAVE.
                
                htField = httTable:BUFFER-FIELD('active') NO-ERROR.
                IF NOT VALID-HANDLE(htField) THEN LEAVE.

                IF hField:BUFFER-VALUE = FALSE AND htField:BUFFER-VALUE = TRUE THEN LEAVE.

                outilitiesHandler:createQuestionBox(
                    INPUT  oJsonIdent       ,
                    INPUT  '2000'           ,
                    INPUT  ''               ,
                    INPUT  'active'         ,
                    INPUT  'true'           ,
                    INPUT  hBuffer          ,
                    OUTPUT oJsonMessageBox
                    ) NO-ERROR.

                oJsonReturn = NEW JsonObject().
                oJsonReturn:ADD('success'     , TRUE            ).
                oJsonReturn:ADD('record'      , oJsonRecord     ).
                oJsonReturn:ADD('askQuestion' , oJsonMessageBox ).
                RETURN TRUE.
            END.

            lOK = hBuffer:BUFFER-COMPARE(httTable, 'case-sensitive') NO-ERROR.
            hBuffer:BUFFER-COPY(httTable) NO-ERROR.
            outilitiesHandler:evaluateErrorStatus(hError).
// MESSAGE 'compare ergab' lOK.
            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('updated_by'):HANDLE NO-ERROR.
            IF  NOT ERROR-STATUS:ERROR AND
                VALID-HANDLE(hField)   THEN hField:BUFFER-VALUE = oJsonIdent:GetCharacter('H_display_name').

            oJsonData   = NEW JsonObject().
            oJsonArray  = NEW JsonArray ().
            httTable:BUFFER-COPY(hBuffer).
            httTable:WRITE-JSON('JsonObject', oJsonData).

            oJsonArray = oJsonData:GetJsonArray('record').
            oJsonData  = oJsonArray:GetJsonObject(1).
            
            hBuffer:BUFFER-RELEASE ().
            
            lRetVal = TRUE.
            LEAVE.
        END.

        IF lWordIndex THEN fillWordIndexTable().

        IF lRetVal THEN 
        DO:             
            oJsonReturn = NEW JsonObject().
            oJsonReturn:ADD('success', TRUE     ).
            oJsonReturn:ADD('record' , oJsonData).
        
            outilitiesHandler:createInfoBox(
                INPUT  oJsonIdent       ,
                INPUT  '2003'           ,
                INPUT  ''               ,
                OUTPUT oJsonMessageBox
                ) NO-ERROR.
            oJsonReturn:ADD('showMessage' , oJsonMessageBox).
            
            RETURN TRUE.
        END.

        IF NOT lRetVal THEN 
        DO:
            oJsonMessage = NEW JsonObject().
            oJsonMessage:ADD('success', FALSE).
            oJsonMessage:ADD('message', lcMessage).
            oJsonMessage:WRITE(lcJsonString, FALSE).
            
            oJsonReturn = oJsonMessage.
            
            RETURN TRUE.
        END.
        
        CATCH e AS Progress.Lang.Error:

        END CATCH.

        FINALLY:

        END FINALLY.

    END METHOD.

    DESTRUCTOR PUBLIC adminprogsHandler ( ):

    END DESTRUCTOR.

END CLASS.