/*------------------------------------------------------------------------
   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 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 addresses.addressprogsHandler 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 iAddress_Id      AS INT64             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 ttcommunication LIKE communication.
    
    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 addressprogsHandler (  ):
        SUPER ().
        
    END CONSTRUCTOR.


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

    CONSTRUCTOR PUBLIC addressprogsHandler ( 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.
        
        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.
        createTempTable().
// MESSAGE 'WHERE-Statement nach buildcWhere =' cWhere.
        RETURN.

    END METHOD.

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

    METHOD PUBLIC LOGICAL changeAnschrift(
        INPUT  oJsonData    AS JsonObject   ,
        OUTPUT oJsonReturn  AS JsonObject
        ):
            
        DEFINE VARIABLE cReplace         AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cFieldName       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 cCompany         AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cFormUser        AS CHARACTER  NO-UNDO.
            
        DEFINE VARIABLE hField           AS HANDLE     NO-UNDO.
        DEFINE VARIABLE cAdresse         AS CHARACTER  NO-UNDO EXTENT 12.
        DEFINE VARIABLE cBriefanrede     AS CHARACTER  NO-UNDO.
        
        DEFINE VARIABLE oJsonRecord      AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonArray       AS JsonArray  NO-UNDO.
        DEFINE VARIABLE oJsonSelectBoxes AS JsonObject NO-UNDO.
        
        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
        //
        outilitiesHandler:evaluateFile(
            INPUT-OUTPUT oJsonIdent     ,
            OUTPUT       cFileName      ,
            OUTPUT       lCompany       ,
            OUTPUT       lActive        ,
            OUTPUT       lWordIndex     ,
            INPUT-OUTPUT httKeyFields   ,
            INPUT-OUTPUT httPrimaryIndex
            ).
            
        cFunction = oJsonIdent:GetCharacter('function').
        cCompany  = oJsonIdent:GetCharacter('company').
        cFormId   = oJsonIdent:GetCharacter('formId').
        cFormUser = oJsonIdent:GetCharacter('formUser').
        
//        CREATE BUFFER hBuffer FOR TABLE cFileName.
//         createTempTable().

        oJsonRecord = NEW JsonObject().
        oJsonRecord = oJsonData:GetJsonObject('record').
// oJsonRecord:WriteFile('C:\Temp\changeanschrift_oJsonRecord.json', TRUE).

        httTable:READ-JSON('JsonObject', oJsonRecord) NO-ERROR.
        outilitiesHandler:evaluateErrorStatus(ERROR-STATUS:HANDLE).
        
// httTable:WRITE-JSON ('FILE', 'C:\TEMP\ttTable_changeAnschrift_Inhalt.json', TRUE).
        //
        //  den ersten Datensatz in der TEMP-TABLE lesen
        //
        httTable:FIND-FIRST('', NO-LOCK) NO-ERROR.
        outilitiesHandler:evaluateErrorStatus(ERROR-STATUS:HANDLE).

        IF  iformTabIndex = 1           AND
            cFileName     = 'addresses' AND
            NOT httTable::address_fix   THEN 
        DO:
            oJsonIdent:SET('language_id', httTable::language_id).
            createAnschrift(
                INPUT-OUTPUT httTable
                ).
        END.

        lOK = httTable:WRITE-JSON ('JsonObject', oJsonRecord).
        lOk = TRUE.
        
        oJsonReturn = NEW JsonObject().
        oJsonReturn:ADD('success', lOK).
        
        oJsonArray  = NEW JsonArray().
        oJsonArray  = oJsonRecord:GetJsonArray('record').
        oJsonRecord = oJsonArray:GetJsonObject(1). 
        oJsonReturn:ADD('record', oJsonRecord).
        
        oselectboxHandler:getVariableSelectBoxes(
            INPUT  oJsonIdent,
            OUTPUT oJsonSelectBoxes
            ).
        IF VALID-OBJECT(oJsonSelectBoxes) THEN oJsonReturn:ADD('selectOptions', oJsonSelectBoxes).
        
//oJsonReturn:WriteFile('C:\Temp\changeAnschrift_return.json', TRUE).
        
        RETURN lOK.

    END METHOD.

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

    METHOD PUBLIC LOGICAL changeFixedAddress(
        INPUT  oJsonData     AS JsonObject   ,
        OUTPUT oJsonReturn   AS JsonObject
        ):
        
        DEFINE VARIABLE lRetVal          AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE lAddressFix      AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE lOk              AS LOGICAL    NO-UNDO.
        
        DEFINE VARIABLE oJsonAction      AS JsonArray  NO-UNDO.
        DEFINE VARIABLE oJsonRecord      AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonArray       AS JsonArray  NO-UNDO.
        DEFINE VARIABLE oJsonSelectBoxes AS JsonObject NO-UNDO.
        
        lAddressFix = LOGICAL(oJsonData:GetCharacter('changedValue')).
        oJsonAction = NEW JsonArray().
        oJsonAction:ADD('addresses_address').
        
        oJsonReturn = NEW JsonObject().
        IF lAddressFix THEN oJsonReturn:ADD('editableFields', oJsonAction).
        ELSE                oJsonReturn:ADD('disabledFields', oJsonAction).

        lRetVal = TRUE.
        
        IF lAddressFix THEN RETURN lRetVal.
        
        cFunction = oJsonIdent:GetCharacter('function').
        cFileName = oJsonIdent:GetCharacter('file_name').

        createTempTable().

        oJsonRecord = NEW JsonObject().
        oJsonRecord = oJsonData:GetJsonObject('record').
// oJsonRecord:WriteFile('C:\Temp\changefixedAddressoJsonRecord.json', TRUE).

        httTable:READ-JSON('JsonObject', oJsonRecord) NO-ERROR.
        outilitiesHandler:evaluateErrorStatus(ERROR-STATUS:HANDLE).
        
// httTable:WRITE-JSON ('FILE', 'C:\TEMP\ttTable_changeFixedAddresses_Inhalt.json', TRUE).
        httTable:FIND-FIRST('', NO-LOCK) NO-ERROR.
        createAnschrift(
            INPUT-OUTPUT httTable
            ).

        lOK = httTable:WRITE-JSON ('JsonObject', oJsonRecord).
        lOk = TRUE.
        
        oJsonReturn:ADD('success', lOK).
        
        oJsonArray  = NEW JsonArray().
        oJsonArray  = oJsonRecord:GetJsonArray('record').
        oJsonRecord = oJsonArray:GetJsonObject(1). 
        oJsonReturn:ADD('record', oJsonRecord).
        
        /*        httTable:FIND-FIRST('', NO-LOCK).                    */
        /*        oJsonIdent:SET('language_id', httTable::language_id).*/
        /*        oselectboxHandler:getVariableSelectBoxes(            */
        /*            INPUT  oJsonIdent,                               */
        /*            OUTPUT oJsonSelectBoxes                          */
        /*            ).                                               */
        IF VALID-OBJECT(oJsonSelectBoxes) THEN oJsonReturn:ADD('selectOptions', oJsonSelectBoxes).
        
        RETURN lRetVal.

    END METHOD.

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

    METHOD PUBLIC VOID createAnschrift(
        INPUT-OUTPUT hRecord AS HANDLE
        ):
            
        DEFINE VARIABLE cAdresse        AS CHARACTER NO-UNDO EXTENT 12.
        DEFINE VARIABLE cBriefAnrede    AS CHARACTER NO-UNDO.
        DEFINE VARIABLE ii              AS INTEGER   NO-UNDO.
        DEFINE VARIABLE iSalutationCode AS INTEGER   NO-UNDO.
        DEFINE VARIABLE cCountryCode    AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cAdressDisplay  AS CHARACTER NO-UNDO.
        DEFINE VARIABLE hField          AS HANDLE    NO-UNDO.
        
        IF hRecord::address_fix THEN RETURN.
        MESSAGE 'start'.        
        iLanguage_id    = hRecord::language_id.
        iSalutationCode = hRecord::salutation_code.
        cCountryCode    = hRecord::country_code.

        cAdresse       = ''.
        cAdressDisplay = ''.
        FIND salutations NO-LOCK 
            WHERE salutations.language_id     = iLanguage_id
            AND   salutations.salutation_code = iSalutationCode NO-ERROR.
        IF  NOT AVAILABLE salutations AND 
            iLanguage_id <> 1         THEN 
        DO:
            FIND salutations NO-LOCK 
                WHERE salutations.language_id     = 1
                AND   salutations.salutation_code = iSalutationCode NO-ERROR.
        END.

        FIND countries NO-LOCK 
            WHERE countries.language_id  = iLanguage_id
            AND   countries.country_code = cCountryCode NO-ERROR.
        IF  NOT AVAILABLE countries AND
            iLanguage_id <> 1       THEN 
        DO:
            FIND countries NO-LOCK 
                WHERE countries.language_id = 1
                AND   countries.country_code = cCountryCode NO-ERROR.
        END.
        IF AVAILABLE countries THEN 
        DO:
            DO ii = 1 TO 3:
                IF countries.country_code_pos = ii THEN 
                DO:
                    cAdresse[11] = cAdresse[11] + hRecord::country_code.
                    IF ii = 1 THEN cAdresse[11] = cAdresse[11] + '-'.
                    ELSE           cAdresse[11] = cAdresse[11] + ' '.
                END.
                IF countries.postal_code_pos = ii THEN 
                DO:
                    cAdresse[11] = cAdresse[11] + hRecord::postal_code + ' '.
                END.
                IF countries.city_pos = ii THEN 
                DO:
                    cAdresse[11] = cAdresse[11] + hRecord::city + ' '.
                END.
            END.
            cAdresse[11] = TRIM(cAdresse[11]).
            IF countries.country_code_pos = 9 THEN cAdresse[12] = TRIM(countries.country_name).
        END.

        ii = 10.
        IF hRecord::po_box <> '' THEN cAdresse[ii] = hRecord::po_box.
        ELSE cAdresse[ii] = TRIM(hRecord::street + ' ' + hRecord::street_no).
        IF cAdresse[ii] <> '' THEN ii = ii - 1.
        cAdresse[ii] = TRIM(hRecord::additional_2).
        IF cAdresse[ii] <> '' THEN ii = ii - 1.
        cAdresse[ii] = TRIM(hRecord::additional_1).
        IF cAdresse[ii] <> '' THEN ii = ii - 1.
        cAdresse[ii] = TRIM(hRecord::address_title + ' ' + hRecord::first_name + ' ' + hRecord::last_name).
        IF cAdresse[ii] <> '' THEN 
        DO:
            IF AVAILABLE salutations THEN 
            DO:
                IF hRecord::company_name_1 <> '' THEN
                    ASSIGN
                        cAdresse[ii] = salutations.to_attention_of + ' ' + cAdresse[ii]
                        cAdresse[ii] = TRIM(cAdresse[ii]).
            END.
            ii  = ii - 1.
        END.
        cAdresse[ii] = TRIM(hRecord::company_name_2).
        IF cAdresse[ii] <> '' THEN ii = ii - 1.
        cAdresse[ii] = TRIM(hRecord::company_name_1).
        IF cAdresse[ii] <> '' THEN ii = ii - 1.
        IF hRecord::company_name_1 = '' AND AVAILABLE salutations THEN cAdresse[ii] = salutations.salutation.

        //hRecord::Address = ''.
        hField = hRecord:BUFFER-FIELD('address'):HANDLE.
        DO ii = 1 TO 12:
            // hRecord::address = hRecord::address + cAdresse[ii].
            hField:BUFFER-VALUE(ii) = cAdresse[ii].
            // IF ii < 12 THEN hRecord::address = hRecord::address + CHR(10).
        END.

        cBriefanrede = (IF AVAILABLE salutations THEN salutations.letterhead_business ELSE '').
        IF hRecord::last_name <> '' THEN cBriefanrede = TRIM(cBriefanrede + ' ' + hRecord::address_title + ' ' + hRecord::last_name).
        hRecord::letter_salutation = cBriefanrede.
        
        IF hRecord::company_name_1 <> ''
            THEN cAdressDisplay = cAdressDisplay
                + (IF cAdressDisplay = '' THEN '' ELSE ',' )
                + TRIM(hRecord::company_name_1 + ' ' + hRecord::company_name_2). 
        IF hRecord::last_name <> ''
            THEN cAdressDisplay = cAdressDisplay
                + (IF cAdressDisplay = '' THEN '' ELSE ',' )
                + TRIM(hRecord::last_name + ' ' + hRecord::first_name). 
        IF hRecord::street <> ''
            THEN cAdressDisplay = cAdressDisplay
                + (IF cAdressDisplay = '' THEN '' ELSE ',' )
                + TRIM(hRecord::street + ' ' + hRecord::street_no). 
        cAdressDisplay = cAdressDisplay
            + (IF cAdressDisplay = '' THEN '' ELSE ',' )
            + TRIM(hRecord::country_code + '-' + hRecord::postal_code + ' ' + hRecord::city). 
        hRecord::address_display = cAdressDisplay.

        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 oInfoRecord      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 iContact_Id      AS INTEGER    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.
        
// oJsonData:WriteFile('C:\TEMP\createBegin_jsondata_request.json', TRUE).        
        oJsonRecord = NEW JsonObject().
        oJsonRecord = oJsonData:GetJsonObject('record').
// oJsonRecord:WriteFile('C:\TEMP\createBegin_jsonrecord_request.json', TRUE).        
        oMasterKeyFields = NEW JsonObject().
        oMasterKeyFields = oJsonData:GetJsonObject('masterKeyfields') NO-ERROR.
// oMasterKeyFields:WriteFile('C:\TEMP\createBegin_MasterKeyFields.json', TRUE).        
        
        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(ERROR-STATUS:HANDLE).
        httTable:FIND-FIRST('', NO-LOCK).

        /*        EXTENT(cFieldNames) = ?.                                                                                          */
        /*        cFieldNames = oMasterKeyFields:GetNames().                                                                        */
        /*        DO ii = 1 TO EXTENT(cFieldNames):                                                                                 */
        /*            cField       = cFieldNames[ii].                                                                               */
        /*            cField       = ENTRY(1, cField, '_').                                                                         */
        /*            cBufferField = SUBSTRING(cField,02).                                                                          */
        /*            hField       = httTable:BUFFER-FIELD(cBufferField):HANDLE NO-ERROR.                                           */
        /*            IF ERROR-STATUS:ERROR        THEN NEXT.                                                                       */
        /*            IF NOT VALID-HANDLE (hField) THEN NEXT.                                                                       */
        /*                                                                                                                          */
        /*            iType = oJsonRecord:getType(cField).                                                                          */
        /*            CASE iType:                                                                                                   */
        /*                WHEN 2 THEN                                                                                               */
        /*                    DO:                                                                                                   */
        /*                        iValue = oJsonRecord:GetInteger(cField).                                                          */
        /*                        hField:BUFFER-VALUE = iValue NO-ERROR.                                                            */
        /*                        oJsonRecord:SET(cField, iValue).                                                                  */
        /*                    END.                                                                                                  */
        /*                WHEN 3 THEN                                                                                               */
        /*                    DO:                                                                                                   */
        /*                        lValue = oJsonRecord:GetLogical(cField).                                                          */
        /*                        hField:BUFFER-VALUE = lValue NO-ERROR.                                                            */
        /*                        oJsonRecord:SET(cField, lValue).                                                                  */
        /*                    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)).*/
        /*                    oJsonRecord:SET(cField, cValue).                                                                      */
        /*                END.                                                                                                      */
        /*            END CASE.                                                                                                     */
        /*            lOk = outilitiesHandler:evaluateErrorStatus(ERROR-STATUS:HANDLE).                                             */
        /*        END.                                                                                                              */
        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.
            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').
            oJsonRecord:SET(SUBSTITUTE('&1_&2', cFileName, 'created_by'), oJsonIdent:GetCharacter('H_display_name')).
        END.
            
        /*        oMasterKeyFields    = NEW JsonObject().                          */
        /*        oMasterKeyFields    = oJsonData:GetJsonObject('masterKeyfields').*/
        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).
        
// oJsonRecord:WriteFile('C:\TEMP\createBegin_jsonrecord_response.json', TRUE).
        
        createInfoRecord(
            OUTPUT oInfoRecord
            ).        

        oJsonReturn = NEW JsonObject().
        oJsonReturn:ADD('success', TRUE).
        oJsonReturn:add('record', oJsonRecord).
        IF VALID-OBJECT(oInfoRecord) THEN oJsonReturn:ADD('infoRecord', oInfoRecord).
// 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 ii               AS INTEGER    NO-UNDO.
        DEFINE VARIABLE i1               AS INTEGER    NO-UNDO.
        DEFINE VARIABLE i2               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(ERROR-STATUS:HANDLE).
        httTable:FIND-FIRST('', NO-LOCK).
        //
        //  Anschrift und Briefanrede erstellen
        //
// MESSAGE 'd'.        
        iFormTabIndex = htt::FormTabIndex.
        IF  iFormTabIndex = 1           AND 
            cFileName     = 'addresses' AND 
            NOT httTable::address_fix   THEN
        DO:
            createAnschrift(
                INPUT-OUTPUT httTable
                ).
        END.

        CASE cFileName:
            WHEN 'addresses' THEN 
                httTable::address_id = NEXT-VALUE(masterdata_id).
            WHEN 'contact_persons' THEN 
                DO:
                    FIND LAST contact_persons NO-LOCK 
                        WHERE contact_persons.company    = cCompany
                        AND   contact_persons.address_Id = oJsonRecord:GetInt64('address_id').
                    iContact_Id = (IF AVAILABLE contact_persons THEN contact_persons.contact_id  + 1 ELSE 1).
                    httTable::contact_id = iContact_Id.
                    httTable::company    = cCompany.
                END.
        END CASE.
        
        createUniqueWhere(
            INPUT  httTable,
            OUTPUT cUniqueWhere
            ).

        lRetVal = FALSE.
        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
            lOK = hBuffer:FIND-UNIQUE(cUniqueWhere, NO-LOCK) NO-ERROR.
            MESSAGE 'find unique mit ' lOK 'und' cUniqueWhere.
            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 / wordindex erstellen
            //
            hBuffer:BUFFER-CREATE().
            hBuffer:BUFFER-COPY(httTable) NO-ERROR.
            /*            DO ii = 1 TO httTable:NUM-FIELDS:                                                  */
            /*                htField = httTable:BUFFER-FIELD(ii):HANDLE NO-ERROR.                           */
            /*                cField  = htField:NAME.                                                        */
            /*                hField  = hBuffer:BUFFER-FIELD(cField):HANDLE NO-ERROR.                        */
            /*                IF  ERROR-STATUS:ERROR       OR                                                */
            /*                    NOT VALID-HANDLE(hField) THEN NEXT.                                        */
            /*                                                                                               */
            /*                IF hField:EXTENT > 0 THEN                                                      */
            /*                DO:                                                                            */
            /*                    cFieldValue = htField:BUFFER-VALUE.                                        */
            /*                    IF cField = 'address' THEN                                                 */
            /*                    DO:                                                                        */
            /*                        FIND countries NO-LOCK                                                 */
            /*                            WHERE countries.language_id  = httTable::language_id               */
            /*                            AND   countries.country_code = httTable::country_code NO-ERROR.    */
            /*                        IF NOT AVAILABLE countries THEN                                        */
            /*                        DO:                                                                    */
            /*                            FIND countries NO-LOCK                                             */
            /*                                WHERE countries.language_id  = 1                               */
            /*                                AND   countries.country_code = httTable::country_code NO-ERROR.*/
            /*                        END.                                                                   */
            /*                        i2 = (IF countries.country_code_pos = 9 THEN 12 ELSE 11).              */
            /*                                                                                               */
            /*                        DO i1 = 1 TO 12:                                                       */
            /*                            hField:BUFFER-VALUE(i1) = ''.                                      */
            /*                        END.                                                                   */
            /*                        DO i1 = NUM-ENTRIES(cFieldValue, CHR(10)) TO 1 BY -1:                  */
            /*                            cValue = ENTRY(i1, cFieldValue, CHR(10)).                          */
            /*                            IF cValue = '' THEN NEXT.                                          */
            /*                            hField:BUFFER-VALUE(i2) = cValue.                                  */
            /*                            i2 = i2 - 1.                                                       */
            /*                        END.                                                                   */
            /*                    END.                                                                       */
            /*                    ELSE                                                                       */
            /*                    DO:                                                                        */
            /*                        DO i1 = 1 TO hField:EXTENT:                                            */
            /*                            hField:BUFFER-VALUE(i1) = ENTRY(i1, cFieldValue, CHR(10)) NO-ERROR.*/
            /*                        END.                                                                   */
            /*                    END.                                                                       */
            /*                END.                                                                           */
            /*                ELSE                                                                           */
            /*                DO:                                                                            */
            /*                    IF htField:BUFFER-VALUE = hField:BUFFER-VALUE THEN NEXT.                   */
            /*                    hField:BUFFER-VALUE = htField:BUFFER-VALUE.                                */
            /*                END.                                                                           */
            /*            END.                                                                               */

            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  cFileName = 'addresses'     OR
            cFileName = 'communication' THEN 
        DO:
            updateCommunication(
                INPUT iContact_Id
                ).
        END.

        IF lRetVal THEN 
        DO:
            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
                ).

            outilitiesHandler:evaluatePageNumber(
                INPUT-OUTPUT oJsonIdent   ,
                INPUT        cWhere       ,
                INPUT        rBuffer
                ).
        
            httTable:EMPTY-TEMP-TABLE ().
            DELETE OBJECT ttTable.            
            createTempTable().
            
            fillTemptableFromTable(
                OUTPUT oJsonReturn
                ).

            CREATE BUFFER hUniqueBuffer FOR TABLE cFileName.
            hUniqueBuffer:FIND-UNIQUE (cUniqueWhere, NO-LOCK) NO-ERROR.
            outilitiesHandler:evaluateErrorStatus(ERROR-STATUS:HANDLE).
            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 = NEW JsonObject().
            oJsonReturn:ADD('success', TRUE     ).
            oJsonReturn:ADD('record' , oJsonData).
        
            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 createInfoRecord(
        OUTPUT oInfoRecord AS JsonObject
        ):
            
        DEFINE VARIABLE cOrigFileName AS CHARACTER NO-UNDO.
        DEFINE VARIABLE cUniqueWhere  AS CHARACTER NO-UNDO.
        DEFINE VARIABLE hUniqueBuffer AS HANDLE    NO-UNDO.
        
        cOrigFileName = oJsonIdent:GetCharacter('file_name').
        oJsonIdent:SET('file_name', 'addresses').
        outilitiesHandler:readLastRecord(
            INPUT  oJsonIdent   ,
            OUTPUT cUniqueWhere
            ).
// MESSAGE 'uniquwhere bei createInfoRecord' cUniqueWhere.
        oJsonIdent:SET('file_name', cOrigFileName).
            
        CREATE BUFFER hUniqueBuffer FOR TABLE 'addresses'.
        hUniqueBuffer:FIND-UNIQUE (cUniqueWhere, NO-LOCK) NO-ERROR.
// MESSAGE 'createInfoRecord address_id ' hUniqueBuffer:AVAILABLE hUniqueBuffer::address_id.

        oInfoRecord = NEW JsonObject().            
        oInfoRecord:ADD('address_id'     , hUniqueBuffer::address_id     ).
        oInfoRecord:ADD('address_display', hUniqueBuffer::address_display).
        
        IF cFileName = 'addresses' THEN 
        DO:
            FIND FIRST customers NO-LOCK 
                WHERE customers.company    = ccompany
                AND   customers.address_id = hUniqueBuffer::address_id NO-ERROR.
            oInfoRecord:ADD('lcustomer', (IF AVAILABLE customers THEN TRUE ELSE FALSE)).
        /*            FIND FIRST creditors NO-LOCK                                                     */
        /*                WHERE creditors.company    = ccompany                                        */
        /*                AND   creditors.address_id = hUniqueBuffer::address_id NO-ERROR.             */
        /*                oInfoRecord:ADD('lcreditor', (IF available creditors THEN TRUE ELSE false)).*/
        /*            FIND FIRST suppliers NO-LOCK                                                     */
        /*                WHERE suppliers.company    = ccompany                                        */
        /*                AND   suppliers.address_id = hUniqueBuffer::address_id NO-ERROR.             */
        /*                oInfoRecord:ADD('lsupplier', (IF available suppliers THEN TRUE ELSE false)).*/
        END.
        
        hUniqueBuffer:BUFFER-RELEASE ().
        DELETE OBJECT hUniqueBuffer.
        
        RETURN.

    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
                VIEW-AS ALERT-BOX.
        END. 

        CREATE TEMP-TABLE ttTable.
        ttTable:ADD-FIELDS-FROM (cFileName, 'wordindex').   /*  Alle Felder aus dem Buffer, ausser wordindex    */

        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.
        CASE cFileName:
        /*            WHEN 'addresses' THEN                                 */
        /*                DO:                                               */
        /*                    ttTable:ADD-NEW-FIELD('lcustomer', 'LOGICAL').*/
        /*                    ttTable:ADD-NEW-FIELD('lcreditor', 'LOGICAL').*/
        /*                    ttTable:ADD-NEW-FIELD('lsupplier', 'LOGICAL').*/
        /*                END.                                              */
        END CASE.
        
        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.
// IF cFileName = 'addresses' THEN MESSAGE 'HALLO ->' httTable:BUFFER-FIELD('address'):NAME ' / ' httTable:BUFFER-FIELD('address'):EXTENT.
        //
        //  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'.
                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'.
            IF hField:NAME = 'address_id' THEN iAddress_Id = INT64(cValue).
        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('C:\TEMP\delete_data.json', TRUE).
        oJsonRecord = NEW JsonObject().
        oJsonRecord = oJsonData:GetJsonObject('record') NO-ERROR.
// oJsonRecord:WriteFile('C:\TEMP\delete_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(ERROR-STATUS:HANDLE).
        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.
// MESSAGE 'gefunden'.
            rBuffer = hBuffer:RECID.
            hBuffer:BUFFER-RELEASE ().

            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.
            iAddress_Id = hBuffer::address_Id.
            iContact_Id =
                (IF cFileName = 'communication' OR cFileName = 'contact_persons' THEN
                hBuffer::contact_id ELSE 0). 
                
            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.
            //
            //  Letzte Abfrage wiederholen und Temp-Tabelle füllen
            //
            outilitiesHandler:readLastcWhere(
                INPUT  oJsonIdent,
                INPUT  cFileName,
                OUTPUT cWhere) NO-ERROR.
            outilitiesHandler:evaluateErrorStatus(ERROR-STATUS:HANDLE).
            
            httTable:EMPTY-TEMP-TABLE ().            
            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  cFileName = 'addresses'     OR 
            cFileName = 'communication' THEN 
        DO:
            updateCommunication(
                INPUT  iContact_Id
                ).
        END.
        fillWordIndexTable().
                
            
        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 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 = REPLACE(cWhere, 'FOR', 'PRESELECT').
        CREATE QUERY  hQuery.
        
        CREATE BUFFER hBuffer FOR TABLE cFileName.
        hQuery:SET-BUFFERS (hBuffer) NO-ERROR.
        outilitiesHandler:evaluateErrorStatus(ERROR-STATUS:HANDLE).

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

        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 ' cWhere.
        DO WHILE NOT hQuery:QUERY-OFF-END:
            IF iCurrentPosition = 0 THEN iCurrentPosition = iStartRecord.
            iAnzahlRecords = iAnzahlRecords + 1.
            httTable:BUFFER-CREATE().
            httTable:BUFFER-COPY(hBuffer).
             
            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', '').
// MESSAGE 'Boxfield-Name' cField.
                    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.
// MESSAGE 'Boxfield ' cField '-' cFieldValue '-' htt::user_name.
                    httTable:BUFFER-FIELD(i1):BUFFER-VALUE =
                        outilitiesHandler:getBoxFieldText(
                        INPUT oJsonIdent ,
                        INPUT cField     ,
                        INPUT cFieldValue
                        ) NO-ERROR. 
// MESSAGE httTable:BUFFER-FIELD(i1):BUFFER-VALUE.
                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).
// oRecords:WriteFile(SUBSTITUTE('C:\TEMP\&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.
        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.
        DEFINE VARIABLE cCommTypes AS CHARACTER NO-UNDO
            INIT '1,2,3,4,6'.
        
        outilitiesHandler = NEW utilitiesHandler().
            
        EMPTY TEMP-TABLE ttWordIndexTable.

        FIND addresses NO-LOCK
            WHERE addresses.address_id = iAddress_id NO-ERROR.
        hwibuffer = BUFFER addresses:HANDLE.
        
        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.
        hwibuffer = ?.
        
        FOR EACH communication NO-LOCK 
            WHERE communication.company    = cCompany
            AND   communication.address_id = iAddress_id:
                
            IF NOT VALID-HANDLE(hwibuffer) THEN hwibuffer = BUFFER communication:HANDLE. 

            DO i1 = 1 TO hwibuffer:NUM-FIELDS:
                hField = hwibuffer:BUFFER-FIELD(i1):HANDLE.
                IF hField:NAME = 'address_id'          THEN NEXT.
                IF hField:NAME = 'company'             THEN NEXT.
                IF hField:NAME = 'comm_type'           THEN NEXT.
                IF INDEX(hField:NAME, 'updated_') > 0  THEN NEXT.
                IF INDEX(hField:NAME, 'created_') > 0  THEN NEXT.
                
                cValue = hField:BUFFER-VALUE ().
                IF cValue = ? THEN NEXT.
                
                IF LOOKUP(TRIM(STRING(communication.comm_type,'>>9')), cCommTypes, ',') > 0 THEN 
                DO:
                    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.
        END.

        hwibuffer = TEMP-TABLE ttWordIndexTable:DEFAULT-BUFFER-HANDLE.
        cValue    = outilitiesHandler:createWordindexFromTable(
            INPUT hwibuffer
            ).

        MESSAGE 'wordIndex =' cValue.            
        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:        
            FIND addresses
                WHERE addresses.address_id = iAddress_id NO-ERROR.
            addresses.wordIndex = cValue.
            RELEASE addresses.
            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 lAddressFix     AS LOGICAL    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
        //
        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(ERROR-STATUS:HANDLE).
            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().

        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
            ).
            
        createInfoRecord(
            OUTPUT oInfoRecord
            ).

        IF VALID-OBJECT(oInfoRecord) THEN oJsonReturn:ADD('infoRecord', oInfoRecord).

        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.
        
        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(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(
        INPUT  oJsonData   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 cValue           AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE lOK              AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE rBuffer          AS RECID      NO-UNDO.
        DEFINE VARIABLE iTotalRecords    AS INTEGER    NO-UNDO.
        DEFINE VARIABLE hFeld            AS HANDLE     NO-UNDO.
        DEFINE VARIABLE cAddress         AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cUniqueWhere     AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE hUniqueBuffer    AS HANDLE     NO-UNDO.
        
        DEFINE VARIABLE oJsonSelectBoxes AS JsonObject NO-UNDO.
        
        outilitiesHandler = NEW utilitiesHandler().
        oselectboxHandler = NEW selectboxHandler().
        
        cFileName = oJsonIdent:GetCharacter('file_name').
        outilitiesHandler:readLastRecord(
            INPUT  oJsonIdent ,
            OUTPUT cUniqueWhere
            ).
// MESSAGE 'cUniqueWhere fuer UNIQE-FIND' cUniqueWhere.
        CREATE BUFFER hUniqueBuffer FOR TABLE cFileName.
        hUniqueBuffer:FIND-UNIQUE (cUniqueWhere, NO-LOCK).
        rBuffer = hUniqueBuffer:RECID.
        oJsonIdent:ADD('rBuffer', INT64(rBuffer)).
// MESSAGE hUniqueBuffer::address_id '-' rBuffer.
        outilitiesHandler:readLastcWhere(
            INPUT  oJsonIdent,
            INPUT  cFileName ,
            OUTPUT cWhere
            ).
        outilitiesHandler:evaluatePageNumber(
            INPUT-OUTPUT oJsonIdent   ,
            INPUT        cWhere       ,
            INPUT        rBuffer
            ).            
// oJsonIdent:WriteFile('C:\TEMP\address_rebuildData_JsonIdent.json', TRUE).        
// MESSAGE 'LAST-WHERE' cWhere.            
       
        createTempTable().
            
        fillTemptableFromTable(
            OUTPUT oJsonReturn
            ).
            
        hUniqueBuffer:FIND-UNIQUE (cUniqueWhere, NO-LOCK) NO-ERROR.
        outilitiesHandler:evaluateErrorStatus(ERROR-STATUS:HANDLE).
        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(ERROR-STATUS:HANDLE).
        //
        //  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       
            ).            

        outilitiesHandler:readLastcWhere(
            INPUT  oJsonIdent   ,
            INPUT  cFileName    ,
            OUTPUT cWhere
            ).

        createInfoRecord(
            OUTPUT oInfoRecord
            ).
        
        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').
        
        IF  cFileName = 'addresses' AND
            iFormTabIndex = 1       THEN 
        DO: 
            lAddressFix = LOGICAL(oJsonRecord:GetJsonText('addresses_address_fix')).
            oJsonAction = NEW JsonArray().
            oJsonAction:ADD('addresses_address').
            oJsonReturn = NEW JsonObject().
            oJsonReturn:ADD('success', TRUE).
            IF lAddressFix THEN oJsonReturn:ADD('editableFields', oJsonAction).
            ELSE                oJsonReturn:ADD('disabledFields', oJsonAction).
        END.
        IF  cFileName = 'addresses' AND
            iFormTabIndex = 2       THEN 
        DO: 
            oJsonAction = NEW JsonArray().
            // oJsonAction:ADD('addresses_address').
            oJsonReturn = NEW JsonObject().
            oJsonReturn:ADD('success', TRUE).
            // IF lAddressFix THEN oJsonReturn:ADD('editableFields', oJsonAction).
            // ELSE                oJsonReturn:ADD('disabledFields', oJsonAction).
        END.
        IF cFileName = 'communication' THEN 
        DO: 
            oJsonAction = NEW JsonArray().
            oJsonAction:ADD('communication_comm_type').
            oJsonReturn = NEW JsonObject().
            oJsonReturn:ADD('success', TRUE).
            oJsonReturn:ADD('disabledFields', oJsonAction).
        END.

        lRetVal = TRUE.
        RETURN lRetVal.

    END METHOD.

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

    METHOD PUBLIC VOID updateCommunication(
        INPUT iContact_Id AS INTEGER  
        ):
            
        DEFINE VARIABLE hBuffer AS HANDLE    NO-UNDO.
        DEFINE VARIABLE cWhere  AS CHARACTER NO-UNDO.
        MESSAGE 'cFileName in updateCommunication' cFileName.

        IF iContact_Id > 0 THEN RETURN.

        EMPTY TEMP-TABLE ttcommunication.

        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
            CASE cFileName:
                WHEN 'addresses' THEN 
                    DO:
                        CREATE BUFFER hBuffer FOR TABLE cFileName.
                        cWhere = SUBSTITUTE('WHERE &1.address_id = &2', cFileName, iAddress_Id).
                        hBuffer:FIND-UNIQUE (cWhere, NO-LOCK).

                        EMPTY TEMP-TABLE ttcommunication.
                        CREATE  ttcommunication.
                        ASSIGN
                            ttcommunication.company    = oJsonIdent:GetCharacter('company')
                            ttcommunication.address_id = hBuffer::address_id
                            ttcommunication.contact_id = iContact_Id
                            ttcommunication.comm_type  = 1
                            ttcommunication.content    = hBuffer::phone_business
                            .
                        CREATE  ttcommunication.
                        ASSIGN
                            ttcommunication.company    = oJsonIdent:GetCharacter('company')
                            ttcommunication.address_id = hBuffer::address_id
                            ttcommunication.contact_id = iContact_Id
                            ttcommunication.comm_type  = 2
                            ttcommunication.content    = hBuffer::phone_private
                            .
                        CREATE  ttcommunication.
                        ASSIGN
                            ttcommunication.company    = oJsonIdent:GetCharacter('company')
                            ttcommunication.address_id = hBuffer::address_id
                            ttcommunication.contact_id = iContact_Id
                            ttcommunication.comm_type  = 3
                            ttcommunication.content    = hBuffer::mobile_business
                            .
                        CREATE  ttcommunication.
                        ASSIGN
                            ttcommunication.company    = oJsonIdent:GetCharacter('company')
                            ttcommunication.address_id = hBuffer::address_id
                            ttcommunication.contact_id = iContact_Id
                            ttcommunication.comm_type  = 4
                            ttcommunication.content    = hBuffer::mobile_private
                            .
                        CREATE  ttcommunication.
                        ASSIGN
                            ttcommunication.company    = oJsonIdent:GetCharacter('company')
                            ttcommunication.address_id = hBuffer::address_id
                            ttcommunication.contact_id = iContact_Id
                            ttcommunication.comm_type  = 5
                            ttcommunication.content    = hBuffer::e-mail.
                        .
                        CREATE  ttcommunication.
                        ASSIGN
                            ttcommunication.company    = oJsonIdent:GetCharacter('company')
                            ttcommunication.address_id = hBuffer::address_id
                            ttcommunication.contact_id = iContact_Id
                            ttcommunication.comm_type  = 6
                            ttcommunication.content    = hBuffer::fax.
                        .
                        CREATE  ttcommunication.
                        ASSIGN
                            ttcommunication.company    = oJsonIdent:GetCharacter('company')
                            ttcommunication.address_id = hBuffer::address_id
                            ttcommunication.contact_id = iContact_Id
                            ttcommunication.comm_type  = 7
                            ttcommunication.content    = hBuffer::homepage.
                        .
                
                        FOR EACH ttcommunication:
                            FIND communication OF ttcommunication NO-ERROR.
                            IF  NOT AVAILABLE communication   AND
                                ttcommunication.content <> '' THEN 
                            DO:
                                CREATE  communication.
                                BUFFER-COPY ttcommunication TO communication.
                                ASSIGN
                                    communication.created_at = TODAY
                                    communication.created_by = oJsonIdent:GetCharacter('H_display_name').
                                NEXT.
                            END.
                            IF  ttcommunication.content = '' AND
                                AVAILABLE communication      THEN 
                            DO:
                                DELETE  communication.
                                NEXT.
                            END.
                            IF ttcommunication.content = '' THEN NEXT.
            
                            IF ttcommunication.content = communication.content THEN NEXT.
                            ASSIGN
                                communication.content    = ttcommunication.content  
                                communication.updated_at = TODAY
                                communication.updated_by = oJsonIdent:GetCharacter('H_display_name').
                            RELEASE communication.
                        END.
                    END.
                    
                WHEN 'communication' THEN 
                    DO:
                        FIND addresses EXCLUSIVE-LOCK 
                            WHERE addresses.address_id = iAddress_Id NO-WAIT NO-ERROR.
                        IF NOT AVAILABLE addresses THEN LEAVE.
                        
                        ASSIGN 
                            addresses.homepage        = ''
                            addresses.phone_business  = ''
                            addresses.phone_private   = ''
                            addresses.mobile_business = ''
                            addresses.mobile_private  = ''
                            addresses.fax            = ''
                            addresses.e-mail         = ''
                            .
                        IF cFunction = 'delete' THEN 
                        DO:
                        END.
                        
                        FOR EACH communication NO-LOCK 
                            WHERE communication.company    = cCompany
                            AND   communication.address_id = iAddress_Id
                            AND   communication.contact_id = iContact_Id:
                                
                            CASE communication.comm_type:
                                WHEN 1 THEN 
                                    addresses.phone_business  = communication.content.
                                WHEN 2 THEN 
                                    addresses.phone_privat    = communication.content.
                                WHEN 3 THEN 
                                    addresses.mobile_business = communication.content.
                                WHEN 4 THEN 
                                    addresses.mobile_privat   = communication.content.
                                WHEN 5 THEN 
                                    addresses.e-mail          = communication.content.
                                WHEN 6 THEN 
                                    addresses.fax             = communication.content.
                                WHEN 7 THEN 
                                    addresses.homepage        = communication.content.
                            END.
                        END.
                        RELEASE addresses.
                    END.
            END CASE.
            
            LEAVE.
        END.
        
        // DELETE OBJECT hBuffer.
        
        RETURN.

    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(ERROR-STATUS:HANDLE).
        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.
            IF INDEX(lcttTable, 'address_id') > 0 THEN iAddress_Id = hBuffer::address_Id.
            IF INDEX(lcttTable, 'contact_id') > 0 THEN iContact_Id = hBuffer::contact_id.
            
            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(ERROR-STATUS:HANDLE).

            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').

            IF NOT lOK THEN 
            DO:
                IF  cFileName = 'addresses'     OR 
                    cFileName = 'communication' THEN 
                DO:
                    updateCommunication(
                        INPUT  iContact_Id
                        ).
                END.
                //
                //  Anschrift und Briefanrede erstellen
                //
                iFormTabIndex = htt::FormTabIndex.
                IF  iFormTabIndex = 1           AND 
                    cFileName     = 'addresses' AND 
                    NOT httTable::address_fix   THEN
                DO:
                    createAnschrift(
                        INPUT-OUTPUT httTable
                        ).
                END.
            END.

            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.
        MESSAGE 'start fillwordindex'.
        fillWordIndexTable().
        MESSAGE 'ende fillwordindex'.

        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 addressprogsHandler ( ):
        
        // DELETE OBJECT ttJsonIdent NO-ERROR.

    END DESTRUCTOR.

END CLASS.