Bläddra i källkod

Summary 2025.12.04 20:00

walter.riechsteiner 1 dag sedan
förälder
incheckning
04d475eee7

+ 17 - 0
GUI/FRAMEWORK.ds

@@ -0,0 +1,17 @@
+Table           Input File              # of Records Read      # of Errors
+-------------------------------------------------------------------------
+
+-               E:\Datenbanken                  15                  0
+
+-               E:\Datenbanken                  75                  0
+
+-               E:\Datenbanken                   9                  0
+
+-               E:\Datenbanken                1161                  0
+
+-               E:\Datenbanken                  12                  0
+
+-               E:\Datenbanken                  13                  0
+
+-               E:\Datenbanken                 177                  0
+

+ 17 - 0
GUI/Ge_MIS.ds

@@ -0,0 +1,17 @@
+Table           Input File              # of Records Read      # of Errors
+-------------------------------------------------------------------------
+
+-               E:\Datenbanken                   2                  0
+
+-               E:\Datenbanken                   4                  0
+
+-               E:\Datenbanken                 818                  0
+
+-               E:\Datenbanken                 448                  0
+
+-               E:\Datenbanken                   0                  0
+
+-               E:\Datenbanken                  11                  0
+
+-               E:\Datenbanken                  41                  0
+

+ 1219 - 0
admin/adminprogsHandler.cls

@@ -0,0 +1,1219 @@
+ 
+/*------------------------------------------------------------------------
+   File        : usersHandler
+   Purpose     : 
+   Syntax      : 
+   Description : 
+   Author(s)   : walter.riechsteiner
+   Created     : Fri Nov 21 11:31:01 CET 2025
+   Notes       : 
+ ----------------------------------------------------------------------*/
+
+
+BLOCK-LEVEL ON ERROR UNDO, THROW.
+
+USING Progress.Json.ObjectModel.JsonObject FROM PROPATH.
+USING Progress.Json.ObjectModel.JsonArray FROM PROPATH.
+USING utilities.utilitiesHandler FROM PROPATH.
+USING Progress.Json.ObjectModel.ObjectModelParser FROM PROPATH.
+USING OpenEdge.DataAdmin.IIndex FROM PROPATH.
+USING OpenEdge.Web.DataObject.Writer.JsonObjectValueWriter FROM PROPATH.
+
+CLASS admin.adminprogsHandler FINAL:
+    DEFINE VARIABLE oJsonData         AS JsonObject        NO-UNDO.
+    DEFINE VARIABLE oJsonArray        AS JsonArray         NO-UNDO.
+    DEFINE VARIABLE oParser           AS ObjectModelParser NO-UNDO.
+    
+    DEFINE VARIABLE cuser_name        AS CHARACTER         NO-UNDO.
+    DEFINE VARIABLE ccompany          AS CHARACTER         NO-UNDO.
+    DEFINE VARIABLE lcJsonString      AS LONGCHAR          NO-UNDO.
+    DEFINE VARIABLE iLanguage_id      AS INTEGER           NO-UNDO.
+
+    DEFINE VARIABLE oRecords          AS JsonArray         NO-UNDO.
+    DEFINE VARIABLE oJsonPosition     AS JsonObject        NO-UNDO.
+        
+    DEFINE VARIABLE cFileName         AS CHARACTER         NO-UNDO.
+    DEFINE VARIABLE lCompany          AS LOGICAL           NO-UNDO.
+    DEFINE VARIABLE lActive           AS LOGICAL           NO-UNDO.
+    DEFINE VARIABLE lWordindex        AS LOGICAL           NO-UNDO.
+    DEFINE VARIABLE iMaxRecords       AS INTEGER           NO-UNDO INIT 20.
+    DEFINE VARIABLE iStartPage        AS INTEGER           NO-UNDO.
+    DEFINE VARIABLE iStartRecord      AS INTEGER           NO-UNDO.
+    DEFINE VARIABLE iPageCounter      AS INTEGER           NO-UNDO.
+    DEFINE VARIABLE iCurrentPosition  AS INTEGER           NO-UNDO.
+    DEFINE VARIABLE cFieldReplace     AS CHARACTER         NO-UNDO.
+    DEFINE VARIABLE cKeyFieldReplace  AS CHARACTER         NO-UNDO.
+    DEFINE VARIABLE cFilterReplace    AS CHARACTER         NO-UNDO.
+    DEFINE VARIABLE cFileReplace      AS CHARACTER         NO-UNDO.
+    DEFINE VARIABLE cKeyFields        AS CHARACTER         NO-UNDO.
+    DEFINE VARIABLE cKeyValues        AS CHARACTER         NO-UNDO.
+    DEFINE VARIABLE cWhere            AS CHARACTER         NO-UNDO.
+    DEFINE VARIABLE cString           AS CHARACTER         NO-UNDO.
+    DEFINE VARIABLE cMessage          AS CHARACTER         NO-UNDO.
+    DEFINE VARIABLE lcMessage         AS LONGCHAR          NO-UNDO.
+    
+    DEFINE VARIABLE iActualPage       AS INTEGER           NO-UNDO.
+    DEFINE VARIABLE cPrimaryKey       AS CHARACTER         NO-UNDO.
+    DEFINE VARIABLE iIndex            AS INTEGER           NO-UNDO.
+    DEFINE VARIABLE iStartIndex       AS INTEGER           NO-UNDO.
+    
+    DEFINE VARIABLE httTable          AS HANDLE            NO-UNDO.
+    DEFINE VARIABLE ttTable           AS HANDLE            NO-UNDO.
+    
+    DEFINE VARIABLE hQuery            AS HANDLE            NO-UNDO.
+    DEFINE VARIABLE hBuffer           AS HANDLE            NO-UNDO.
+    
+    DEFINE VARIABLE outilitiesHandler AS utilitiesHandler  NO-UNDO.
+    
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD PUBLIC LOGICAL createData(
+        INPUT  oJsonIdent  AS JsonObject,
+        INPUT  oJsonRecord AS jsonObject,
+        OUTPUT oJsonReturn AS JsonObject  
+        ):
+            
+        DEFINE VARIABLE oJsonMessage  AS JsonObject NO-UNDO.
+        DEFINE VARIABLE oJsonPosition AS JsonObject NO-UNDO.
+
+        DEFINE VARIABLE lRetVal       AS LOGICAL    NO-UNDO.
+        DEFINE VARIABLE lOK           AS LOGICAL    NO-UNDO.
+        DEFINE VARIABLE ii            AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE i1            AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE iIndex        AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE cWordIndex    AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cSortField    AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cDirection    AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE hField        AS HANDLE     NO-UNDO.
+        DEFINE VARIABLE htField       AS HANDLE     NO-UNDO.
+        DEFINE VARIABLE cField        AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cValue        AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cIndexFields  AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE rBuffer       AS RECID      NO-UNDO.
+
+        outilitiesHandler = NEW utilitiesHandler().
+
+        outilitiesHandler:evaluateFile(
+            INPUT  oJsonIdent   ,
+            OUTPUT cFileName    ,
+            OUTPUT lCompany     ,
+            OUTPUT lActive      ,
+            OUTPUT lWordindex
+            ).
+            
+        cFieldReplace    = SUBSTITUTE('&1_', cFileName).
+        cKeyFieldReplace = SUBSTITUTE('keyfield_&1_', cFileName).
+        cFilterReplace   = SUBSTITUTE('filter_&1_', cFileName).
+        cFileReplace     = SUBSTITUTE('&1_', cFileName).
+        iLanguage_id     = oJsonIdent:GetInteger('language_id').
+
+        lOK = outilitiesHandler:getKeyFields(
+            INPUT  oJsonIdent   ,
+            OUTPUT cKeyFields   ,
+            OUTPUT cKeyValues
+            ).
+
+        CREATE TEMP-TABLE ttTable.
+        ttTable:ADD-FIELDS-FROM (cFileName, 'wordindex'). /*  except Field wordindex  */
+        ttTable:TEMP-TABLE-PREPARE ('record').
+        httTable = ttTable:DEFAULT-BUFFER-HANDLE.
+
+        DO ii = 1 TO httTable:NUM-FIELDS:
+            httTable:BUFFER-FIELD(ii):SERIALIZE-NAME = cFileName + '_' + httTable:BUFFER-FIELD(ii):NAME NO-ERROR.
+        END.
+
+        httTable:READ-JSON('JsonObject', oJsonRecord) NO-ERROR.
+        httTable:FIND-FIRST('', NO-LOCK).
+        
+        CREATE BUFFER hBuffer FOR TABLE cFileName.
+        cIndexFields = outilitiesHandler:getPrimaryIndexFields(
+            INPUT cFileName
+            ).
+
+        cWhere = ''.    
+        DO i1 = 1 TO NUM-ENTRIES(cIndexFields, ';'):
+            cField = ENTRY(i1, cIndexFields, ';').
+            hField = httTable:BUFFER-FIELD(cField):HANDLE.
+            CASE hField:DATA-TYPE:
+                WHEN 'character' THEN 
+                    cValue = QUOTER(hField:BUFFER-VALUE).
+                WHEN 'logical'   THEN 
+                    cValue = STRING(hField:BUFFER-VALUE,"TRUE/FALSE").
+                WHEN 'date'      THEN 
+                    cValue = STRING(DATE(hField:BUFFER-VALUE)).
+                OTHERWISE             
+                cValue = hField:BUFFER-VALUE. 
+            END CASE.
+            cWhere = cWhere
+                + (IF cWhere = '' THEN 'WHERE ' ELSE ' AND ')
+                + SUBSTITUTE('&1.&2 = ', cFileName, cField)
+                + cValue.
+        END.
+
+        lRetVal = FALSE.
+        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
+            lOK = hBuffer:FIND-UNIQUE(cWhere) NO-ERROR. 
+            IF hBuffer:AVAILABLE THEN 
+            DO:
+                outilitiesHandler:getErrorMessage(
+                    INPUT  '1023',
+                    INPUT  ilanguage_id,
+                    INPUT  '',
+                    OUTPUT lcMessage).
+                LEAVE.
+            END.
+
+            hBuffer:BUFFER-CREATE ().
+            DO ii = 1 TO httTable:NUM-FIELDS:
+                hField  = hBuffer:BUFFER-FIELD(ii):HANDLE NO-ERROR.
+                IF  ERROR-STATUS:ERROR       OR
+                    NOT VALID-HANDLE(hField) THEN NEXT.
+                    
+                htField = httTable:BUFFER-FIELD(ii):HANDLE NO-ERROR.
+                IF htField:BUFFER-VALUE = hField:BUFFER-VALUE THEN NEXT.
+                hField:BUFFER-VALUE = htField:BUFFER-VALUE. 
+            END.
+            htField = httTable:BUFFER-FIELD('created_at'):HANDLE NO-ERROR.
+            IF  NOT ERROR-STATUS:ERROR AND 
+                VALID-HANDLE(htField)  THEN htField:BUFFER-VALUE = NOW.
+            
+            htField = httTable:BUFFER-FIELD('wordindex'):HANDLE NO-ERROR.
+            IF  NOT ERROR-STATUS:ERROR AND 
+                VALID-HANDLE(htField)  THEN 
+            DO:
+                cWordIndex = outilitiesHandler:createWordindex(
+                    INPUT hBuffer
+                    ).
+                htField:BUFFER-VALUE = cWordIndex.
+            END.
+            rBuffer = hBuffer:RECID.
+            hBuffer:BUFFER-RELEASE ().
+            
+            lRetVal = TRUE.
+            LEAVE.
+        END.
+        
+        DO WHILE TRUE:
+            outilitiesHandler:readLastcWhere(
+                INPUT  oJsonIdent,
+                INPUT  cFileName ,
+                OUTPUT cWhere
+                ).
+// MESSAGE 'readlastcwhere = ' cWhere.
+            ASSIGN 
+                ii               = 0
+                i1               = 0
+                iActualPage      = 0
+                iCurrentPosition = 0.
+        
+            ttTable:EMPTY-TEMP-TABLE ().
+            CREATE QUERY hQuery.
+            hQuery:SET-BUFFERS   (hBuffer) NO-ERROR.
+            hQuery:QUERY-PREPARE (cWhere)  NO-ERROR.
+            hQuery:QUERY-OPEN ().
+            hQuery:GET-FIRST  ().
+// MESSAGE 'cPrimaryKey = ' cPrimaryKey '- cWhere = ' cWhere.
+            lOK = FALSE.
+            DO WHILE NOT hQuery:QUERY-OFF-END:
+                ii = ii + 1.
+                IF ii < iStartRecord THEN 
+                DO:
+                    hQuery:GET-NEXT ().
+                    NEXT.
+                END.
+                IF  NOT lOK                AND
+                    ii MOD iMaxRecords = 1 THEN iActualPage = iActualPage + 1.
+                IF NOT lOK THEN 
+                DO:
+                    IF hBuffer:RECID <> rBuffer THEN 
+                    DO:
+                        hQuery:GET-NEXT().
+                        NEXT.
+                    END.
+                    iIndex = ii MOD iMaxRecords.
+                    iStartIndex = ii - iIndex + 1.
+                    DO WHILE ii > iStartIndex:
+                        hQuery:GET-PREV ().
+                        ii = ii - 1.
+                    END.
+                    lOK = TRUE.
+                END.
+                IF iCurrentPosition = 0 THEN iCurrentPosition = ii.
+                i1 = i1 + 1.
+                hQuery:GET-NEXT ().
+            END.
+            hQuery:QUERY-CLOSE ().
+            DELETE OBJECT hBuffer NO-ERROR.
+        
+            IF ii = 0 THEN RETURN FALSE.
+
+            iPageCounter = ii / iMaxRecords.
+            IF (iPageCounter * iMaxRecords) < ii THEN iPageCounter = iPageCounter + 1. 
+ 
+            oJsonPosition = NEW JsonObject().
+            oJsonPosition:ADD('page' , iActualPage).
+            oJsonPosition:ADD('index', iIndex - 1).     /* -1 weil in Java beginnt Index bei 0  */
+        
+            oRecords = NEW JsonArray().
+            httTable:WRITE-JSON('JsonArray', oRecords).
+        
+            oJsonReturn = NEW JsonObject().
+            // oJsonReturn:ADD('records'   , oRecords).
+            oJsonReturn:ADD('maxRecords', ii).
+            oJsonReturn:ADD('pageCount' , iPageCounter).
+            oJsonReturn:ADD('position'  , oJsonPosition).
+            outilitiesHandler:writePosition(
+                INPUT  oJsonIdent       ,
+                INPUT  cFileName        ,
+                INPUT  iCurrentPosition 
+                ).
+            
+            lRetVal = TRUE.        
+            RETURN lRetVal.
+        END.
+
+        IF NOT lRetVal THEN 
+        DO:
+            oJsonMessage = NEW JsonObject().
+            oJsonMessage:ADD('success', FALSE).
+            oJsonMessage:ADD('message', lcMessage).
+            oJsonMessage:WRITE(lcJsonString, FALSE).
+            
+            oJsonReturn = oJsonMessage.
+        END.
+        
+        RETURN lRetVal.
+
+        CATCH e AS Progress.Lang.Error:
+
+        END CATCH.
+
+        FINALLY:
+
+        END FINALLY.
+
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD PUBLIC LOGICAL deleteData(
+        INPUT  oJsonIdent  AS JsonObject,
+        INPUT  oJsonRecord AS jsonObject,
+        OUTPUT oJsonReturn AS JsonObject  
+        ):
+
+        DEFINE VARIABLE oJsonMessage  AS JsonObject NO-UNDO.
+        DEFINE VARIABLE oJsonPosition AS JsonObject NO-UNDO.
+
+        DEFINE VARIABLE lRetVal       AS LOGICAL    NO-UNDO.
+        DEFINE VARIABLE lOK           AS LOGICAL    NO-UNDO.
+        DEFINE VARIABLE ii            AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE i1            AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE iIndex        AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE cWordIndex    AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cSortField    AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cDirection    AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE hField        AS HANDLE     NO-UNDO.
+        DEFINE VARIABLE cField        AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cValue        AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cIndexFields  AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE rBuffer       AS ROWID      NO-UNDO.
+
+        outilitiesHandler = NEW utilitiesHandler().
+
+        outilitiesHandler:evaluateFile(
+            INPUT  oJsonIdent   ,
+            OUTPUT cFileName    ,
+            OUTPUT lCompany     ,
+            OUTPUT lActive      ,
+            OUTPUT lWordindex
+            ).
+            
+        cFieldReplace    = SUBSTITUTE('&1_', cFileName).
+        cKeyFieldReplace = SUBSTITUTE('keyfield_&1_', cFileName).
+        cFilterReplace   = SUBSTITUTE('filter_&1_', cFileName).
+        cFileReplace     = SUBSTITUTE('&1_', cFileName).
+        iLanguage_id     = oJsonIdent:GetInteger('language_id').
+        ccompany         = oJsonIdent:GetCharacter('company').
+
+        lOK = outilitiesHandler:getKeyFields(
+            INPUT  oJsonIdent   ,
+            OUTPUT cKeyFields   ,
+            OUTPUT cKeyValues
+            ).
+
+        CREATE TEMP-TABLE ttTable.
+        ttTable:ADD-FIELDS-FROM (cFileName, 'wordindex'). /*  except Field wordindex  */
+        ttTable:TEMP-TABLE-PREPARE ('record').
+        httTable = ttTable:DEFAULT-BUFFER-HANDLE.
+
+        DO ii = 1 TO httTable:NUM-FIELDS:
+            httTable:BUFFER-FIELD(ii):SERIALIZE-NAME = cFileName + '_' + httTable:BUFFER-FIELD(ii):NAME NO-ERROR.
+        END.
+
+        httTable:READ-JSON('JsonObject', oJsonRecord) NO-ERROR.
+        httTable:FIND-FIRST('', NO-LOCK).
+
+        //  Primary-Index-Fields fuer WHERE-Statement        
+        CREATE BUFFER hBuffer FOR TABLE cFileName.
+        cIndexFields = outilitiesHandler:getPrimaryIndexFields(
+            INPUT cFileName
+            ).
+
+        //  Erzeugen von Where-Statement für UNIQUE-Find
+        cWhere = ''.    
+        DO i1 = 1 TO NUM-ENTRIES(cIndexFields, ';'):
+            cField = ENTRY(i1, cIndexFields, ';').
+            hField = httTable:BUFFER-FIELD(cField):HANDLE.
+            CASE hField:DATA-TYPE:
+                WHEN 'character' THEN 
+                    cValue = QUOTER(hField:BUFFER-VALUE).
+                WHEN 'logical'   THEN 
+                    cValue = STRING(hField:BUFFER-VALUE,"TRUE/FALSE").
+                WHEN 'date'      THEN 
+                    cValue = STRING(DATE(hField:BUFFER-VALUE)).
+                OTHERWISE             
+                cValue = hField:BUFFER-VALUE. 
+            END CASE.
+            cWhere = cWhere
+                + (IF cWhere = '' THEN 'WHERE ' ELSE ' AND ')
+                + SUBSTITUTE('&1.&2 = ', cFileName, cField)
+                + cValue.
+        END.
+                
+        lRetVal = FALSE.
+        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
+            lOK = hBuffer:FIND-UNIQUE (cWhere, NO-LOCK ) NO-ERROR.
+            IF NOT lOK THEN 
+            DO:
+                outilitiesHandler:getErrorMessage(
+                    INPUT  '1014',
+                    INPUT  ilanguage_id,
+                    INPUT  '',
+                    OUTPUT lcMessage).
+                LEAVE.
+            END.
+            rBuffer = hBuffer:ROWID.
+
+            FIND userdata
+                WHERE userdata.user_name   = oJsonIdent:GetCharacter('user_name')
+                AND   userdata.company     = oJsonIdent:GetCharacter('company')
+                AND   userdata.branch      = '0000'
+                AND   userdata.record_type = 'sortField'
+                AND   userdata.section     = cFileName 
+                AND   userdata.key_type    = '' NO-ERROR.
+            IF AVAILABLE userdata THEN 
+            DO: 
+                ASSIGN 
+                    cSortField = userdata.cfield_1
+                    cDirection = userdata.cfield_2.
+            END.
+            IF cDirection BEGINS 'asc' THEN cDirection = ''.
+                    
+            //  Where-Statement f�r FOR EACH Filename f�r die Anzeige            
+            cWhere  = ''.
+            IF lCompany THEN cWhere = SUBSTITUTE('WHERE &1.company = &2', cFileName, QUOTER(ccompany)).
+            IF cKeyFields <> '' THEN
+            DO:
+                DO ii = 1 TO NUM-ENTRIES(cKeyFields, ';'):
+                    cField = ENTRY(ii, cKeyFields, ';').
+                    cField = REPLACE(cField, cKeyFieldReplace, '').
+                    cField = REPLACE(cField, cFilterReplace, '').
+                    cField = REPLACE(cField, cFileReplace, '').
+                    cValue = ENTRY(ii, cKeyValues, CHR(01)).
+                    IF  lCompany           AND
+                        cFIeld = 'company' THEN NEXT.                  
+                    cValue = ENTRY(ii, cKeyValues, CHR(01)).
+                    cWhere = cWhere
+                        + (IF cWhere = '' THEN 'WHERE &1.&2 = &3' ELSE ' AND &1.&2 = &3').
+                    cWhere = SUBSTITUTE(cWhere, cFileName, cField, cValue).
+                END.
+            END.
+
+            CREATE QUERY hQuery.
+            hQuery:SET-BUFFERS (hBuffer).
+            cWhere = SUBSTITUTE('FOR EACH &1 NO-LOCK &2 ', cFileName, cWhere).
+            IF cSortField <> '' THEN cWhere = cWhere + ' BY ' + cSortField + ' ' + cDirection.
+            
+            hQuery:QUERY-PREPARE(cWhere).
+            hQuery:QUERY-OPEN().
+            hQuery:GET-FIRST().
+            
+            ii = 0.
+            i1 = 0.  
+            DO WHILE NOT hQuery:QUERY-OFF-END:
+                ii = ii + 1.
+                IF hBuffer:ROWID = rBuffer THEN i1 = ii.
+                hQuery:GET-NEXT ().
+            END.
+            hQuery:QUERY-CLOSE ().
+        
+            iPageCounter = i1 / iMaxRecords.
+            IF (iPageCounter * iMaxRecords) < i1 THEN iPageCounter = iPageCounter + 1.
+
+            iIndex = i1 MOD iMaxRecords.
+            IF iIndex = 0 THEN iIndex = iMaxRecords.
+            
+            lOK = hBuffer:FIND-BY-ROWID (rBuffer, EXCLUSIVE-LOCK) NO-ERROR.
+            hField = hBuffer:BUFFER-FIELD('active'):HANDLE NO-ERROR.
+            IF  NOT ERROR-STATUS:ERROR AND
+                VALID-HANDLE(hField) THEN 
+            DO:
+                hField:BUFFER-VALUE = FALSE.
+                hField = hBuffer:BUFFER-FIELD('updated_at'):HANDLE NO-ERROR.
+                IF  NOT ERROR-STATUS:ERROR AND 
+                    VALID-HANDLE(hField)   THEN hField:BUFFER-VALUE = NOW.
+            END.
+            ELSE 
+            DO:
+                hBuffer:BUFFER-DELETE ().
+            END.
+            hBuffer:BUFFER-RELEASE ().
+            
+            lRetVal     = TRUE.
+            oJsonReturn = NEW JsonObject().
+            oJsonReturn:ADD('success', lRetVal).
+            
+            oJsonPosition = NEW JsonObject().
+            oJsonPosition:ADD('page', iPageCounter).
+            oJsonPosition:ADD('index', iIndex - 1).     /* -1 weil in Java beginnt Index bei 0  */
+            oJsonPosition:ADD('totalRecords', ii).
+            
+            oJsonReturn:ADD('position', oJsonPosition).
+
+            LEAVE.
+        END.
+                
+        RETURN lRetVal.
+        
+        CATCH e AS Progress.Lang.Error:
+        
+        END CATCH.
+        
+        FINALLY:
+        
+        END FINALLY.
+
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD PUBLIC LOGICAL getChanges(
+        INPUT  oJsonIdent  AS JsonObject,
+        OUTPUT oJsonResult AS JsonObject
+        ):
+    /*
+              DEFINE VARIABLE lRetVal           AS LOGICAL    NO-UNDO.
+                          
+              DEFINE VARIABLE cFunction         AS CHARACTER  NO-UNDO.
+              DEFINE VARIABLE cField            AS CHARACTER  NO-UNDO.
+              DEFINE VARIABLE cAction           AS CHARACTER  NO-UNDO.
+              DEFINE VARIABLE cValue            AS CHARACTER  NO-UNDO.
+              DEFINE VARIABLE lcJsonString      AS LONGCHAR   NO-UNDO.
+              DEFINE VARIABLE cWhere            AS CHARACTER  NO-UNDO.
+                          
+              DEFINE VARIABLE i1                AS INTEGER    NO-UNDO.
+              DEFINE VARIABLE i2                AS INTEGER    NO-UNDO.
+                          
+              DEFINE VARIABLE oJsonfieldUpdates AS JsonObject NO-UNDO.
+                          
+              outilitiesHandler = NEW utilitiesHandler().
+                          
+              cField  = oJsonIdent:GetCharacter('field').
+              cAction = oJsonIdent:GetCharacter('action').
+              cValue  = REPLACE(oJsonIdent:GetCharacter('value'), '+', ' ').
+                  
+              oJsonResult       = NEW JsonObject().
+              oJsonFieldUpdates = NEW JsonObject().
+                  
+              lRetVal = outilitiesHandler:getKeyFields(
+                  INPUT  oJsonIdent   ,
+                  OUTPUT cKeyFields   ,
+                  OUTPUT cKeyValues
+                  ).
+              cWhere     = ''.
+              lRetVal    = FALSE.
+              DO WHILE TRUE:
+                  DO i1 = 1 TO NUM-ENTRIES(cKeyFields, ';'):
+                      cWhere = cWhere
+                          + (IF cWhere = '' THEN 'WHERE ' ELSE 'AND ' )
+                          + SUBSTITUTE('busers.&1 = &2 ',
+                          REPLACE(ENTRY(i1, cKeyFields, ';'), 'users_', ''),
+                          QUOTER (ENTRY(i1, cKeyValues, CHR(01)))).
+                  END.
+                  MESSAGE cWhere.
+                  hBuffer = BUFFER busers:HANDLE.
+                  lRetVal = hBuffer:FIND-UNIQUE(cWhere, NO-LOCK) NO-ERROR.
+                  IF lRetVal THEN 
+                  DO:
+                      CASE cField:
+                          WHEN 'users_firstname' THEN 
+                              DO:
+                                  IF hBuffer::display_Name = '' THEN 
+                                  DO:
+                                      cString = cValue + ' ' + hBuffer::lastname.
+                                      oJsonfieldUpdates:ADD('users_display_name', cString).
+                                  END.
+                                  IF hBuffer::initials = '' THEN 
+                                  DO:
+                                      cString = TRIM(SUBSTRING(cValue,01,02)) + TRIM(SUBSTRING(hBuffer::lastname,01,02)).
+                                      oJsonfieldUpdates:ADD('users_initials', cString).
+                                  END.
+                              END.
+                      END CASE.
+                      oJsonResult:ADD('fieldUpdates', oJsonfieldUpdates).
+                  END.
+                          
+                  lRetVal = TRUE.
+                  LEAVE.
+              END.
+                  
+              IF NOT lRetVal THEN 
+              DO:
+                  oJsonResult = NEW JsonObject().
+                  oJsonResult:ADD('success', FALSE).
+                  oJsonResult:ADD('message', 'Fehler beim change').
+              END.
+                                  
+              RETURN lRetVal.
+    */
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD PUBLIC LOGICAL getData(
+        INPUT  oJsonIdent  AS JsonObject,
+        OUTPUT oJsonReturn AS JsonObject  
+        ):
+        
+        DEFINE VARIABLE ii           AS INTEGER   NO-UNDO.
+        DEFINE VARIABLE i1           AS INTEGER   NO-UNDO.
+        DEFINE VARIABLE iNumerisch   AS INTEGER   NO-UNDO.
+        DEFINE VARIABLE lRetVal      AS LOGICAL   NO-UNDO.
+        DEFINE VARIABLE cSortField   AS CHARACTER NO-UNDO INIT ''.
+        DEFINE VARIABLE cSearchChars AS CHARACTER NO-UNDO INIT ''.
+        DEFINE VARIABLE cValue       AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE lSearch      AS LOGICAL   NO-UNDO INIT FALSE.
+        DEFINE VARIABLE cDirection   AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE cFilters     AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE cFilter      AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE cFields      AS CHARACTER NO-UNDO EXTENT.
+        DEFINE VARIABLE cField       AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE cDBField     AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE cWhere       AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE cType        AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE lChange      AS LOGICAL   NO-UNDO.
+        DEFINE VARIABLE lOK          AS LOGICAL   NO-UNDO.
+        
+        DEFINE VARIABLE oRecords     AS JsonArray NO-UNDO.
+        
+        outilitiesHandler = NEW utilitiesHandler().
+        
+        //
+        //  Ermitteln des Tabellennamens, ob die Tabelle das Feld "company" und/oder das Feld "active" enthält
+        outilitiesHandler:evaluateFile(
+            INPUT  oJsonIdent   ,
+            OUTPUT cFileName    ,
+            OUTPUT lCompany     ,
+            OUTPUT lActive      ,
+            OUTPUT lWordindex
+            ).
+            
+        cFieldReplace    = SUBSTITUTE('&1_', cFileName).
+        cKeyFieldReplace = SUBSTITUTE('keyfield_&1_', cFileName).
+        cFilterReplace   = SUBSTITUTE('filter_&1_', cFileName).
+        
+        lOK = outilitiesHandler:getKeyFields(
+            INPUT  oJsonIdent   ,
+            OUTPUT cKeyFields   ,
+            OUTPUT cKeyValues
+            ).
+        
+        CREATE BUFFER hBuffer FOR TABLE cFileName.
+        
+        cuser_name = oJsonIdent:GetCharacter('user_name').
+        ccompany   = oJsonIdent:GetCharacter('company').
+        lChange    = (IF oJsonIdent:HAS('change') THEN TRUE ELSE FALSE).
+        cSortField = ''.
+        cDirection = ''.
+        cWhere     = ''.
+        iStartPage = 1.
+        IF oJsonIdent:HAS('page') THEN iStartPage = INTEGER(oJsonIdent:GetCharacter('page')) NO-ERROR.
+        iStartRecord = ((iStartPage - 1) * iMaxRecords) + 1. 
+        
+        IF oJsonIdent:HAS('search') THEN 
+        DO:
+            cSearchChars = oJsonIdent:GetCharacter('search').
+            cSearchChars = REPLACE(cSearchChars, '+', ' ').
+            lSearch      = TRUE.
+            iMaxRecords  = 100.
+            iStartRecord = 1.
+        END.
+        
+        IF lCompany THEN cWhere = SUBSTITUTE('WHERE &1.company = &2', cFileName, QUOTER(ccompany)).
+        IF cKeyFields <> '' THEN 
+        DO:
+            DO ii = 1 TO NUM-ENTRIES(cKeyFields, ';'):
+                cString = ENTRY(ii, cKeyFIelds, ';').
+                cString = REPLACE(cString, cKeyFieldReplace, '').
+                cString = REPLACE(cString, cFieldReplace, '').
+                IF cString = 'company' AND lCompany THEN NEXT.
+                cValue  = ENTRY(ii, cKeyValues, CHR(01)). 
+                cString = SUBSTITUTE('&1.&2 = &3 ', cFileName, cString, cValue).
+                cWhere  = cWhere + (IF cWhere = '' THEN 'WHERE ' ELSE ' AND ') + cString.
+            END.
+        END.
+        outilitiesHandler:writeStartcWhere(
+            INPUT  oJsonIdent,
+            INPUT  cFileName ,
+            INPUT  cWhere
+            ).
+// MESSAGE 'Start - cWhere ' cWhere.
+        IF lSearch THEN
+        DO:
+            DO ii = 1 TO NUM-ENTRIES(cSearchChars, ' '):
+                cValue     = ENTRY(ii, cSearchChars, ' ').
+                iNumerisch = INTEGER(cValue) NO-ERROR.
+                cWhere = cWhere + (IF cWhere = '' THEN ' WHERE ' ELSE 'AND ').
+                IF  NOT ERROR-STATUS:ERROR AND
+                    iNumerisch > 0         THEN cValue = SUBSTITUTE('&1&2&1', CHR(01), TRIM(STRING(iNumerisch,'>>>>>>>>9-'))).
+                cWhere = cWhere + 'LOOKUP(' + QUOTER(cValue) + ', ' + cFileName + '.wordindex, " ") > 0 '. 
+            END.
+        END.
+        ELSE 
+        DO: 
+            IF oJsonIdent:HAS('sortField') THEN 
+            DO:
+                cSortField = REPLACE(oJsonIdent:GetCharacter('sortField'), cFieldReplace, '').
+                cDirection = oJsonIdent:GetCharacter('sortDirection').
+            END.
+              
+            outilitiesHandler:writeSortfields(
+                INPUT  oJsonIdent,
+                INPUT  cFileName ,
+                INPUT  cSortField ,
+                INPUT  cDirection 
+                ).
+        
+            cFields = oJsonIdent:GetNames().
+            DO i1 = 1 TO EXTENT(cFields):
+                cField = cFields[i1].
+                IF NOT cField BEGINS 'filter_' THEN NEXT. 
+                cFilter = oJsonIdent:GetCharacter(cField).
+                cField  = REPLACE(cField, cFilterReplace, '').
+                cType   = hBuffer:BUFFER-FIELD(cField):DATA-TYPE.
+                CASE cType:
+                    WHEN 'character' THEN 
+                        cFilter = QUOTER(cFilter).
+                    WHEN 'logical'   THEN 
+                        cFilter = STRING(cFilter,'yes/no').
+                    WHEN 'date'      THEN 
+                        cFilter = STRING(DATE(cFilter),'99.99.9999').
+                END CASE.
+                cDBField = SUBSTITUTE('&1.&2', cFileName, cField).
+                cWhere = cWhere
+                    + (IF cWhere = '' THEN 'WHERE ' ELSE 'AND ')
+                    + 'INDEX(' + cDBField + ', ' + cFilter + ') > 0 '.
+            END.
+        END.
+// MESSAGE 'cWhere = ' cWhere.
+
+        IF NOT cDirection BEGINS 'des' THEN cDirection = ''.
+        IF cSortField <> '' THEN cWhere = cWhere + 'BY ' + cSortField + ' ' + cDirection.
+         
+        CREATE TEMP-TABLE ttTable.
+        ttTable:ADD-FIELDS-FROM (cFilename, 'wordindex').
+        IF cSortField <> '' THEN 
+        DO:
+            ttTable:ADD-NEW-INDEX ('ttTable-k1', FALSE, TRUE).     /*  UNIQUE, PRIMARY */
+            IF cDirection BEGINS 'des' THEN ttTable:ADD-INDEX-FIELD ('ttTable-k1', cSortField, 'desc').
+            ELSE                            ttTable:ADD-INDEX-FIELD ('ttTable-k1', cSortField).
+        END.
+        ttTable:TEMP-TABLE-PREPARE ('records').
+        httTable = ttTable:DEFAULT-BUFFER-HANDLE.
+         
+        DO ii = 1 TO httTable:NUM-FIELDS:
+            httTable:BUFFER-FIELD(ii):SERIALIZE-NAME = cFileName + '_' + httTable:BUFFER-FIELD(ii):NAME NO-ERROR.
+        END.
+// MESSAGE 'cWhere beim Start des lesens ' cWhere.
+        ii = 0.
+        i1 = 0.
+        ttTable:EMPTY-TEMP-TABLE ().
+        CREATE QUERY hQuery.
+        cWhere = SUBSTITUTE('FOR EACH &1 NO-LOCK &2 ', cFileName, cWhere) NO-ERROR.
+// MESSAGE 'writeLastcWhere fuer Datei' cFileName 'ist' cWhere.
+        outilitiesHandler:writeLastcWhere(
+            INPUT  oJsonIdent ,
+            INPUT  cFileName  ,
+            INPUT  cWhere
+            ).
+        MESSAGE 'cWhere vor replacing ' cWhere.
+        cWhere = REPLACE(cWhere, 'FOR', 'PRESELECT').         
+        MESSAGE 'cWhere nach replacing ' cWhere.
+        hQuery:SET-BUFFERS (hBuffer) NO-ERROR.
+        hQuery:QUERY-PREPARE (cWhere) NO-ERROR.
+        hQuery:QUERY-OPEN ().
+        /*        hQuery:GET-LAST ().*/
+        MESSAGE 'Azzahl Query-Datensaetze = ' hQuery:NUM-RESULTS.
+        hQuery:GET-FIRST ().
+
+        iCurrentPosition = 0.
+        DO WHILE NOT hQuery:QUERY-OFF-END:
+            ii = ii + 1.
+            IF ii < iStartRecord THEN 
+            DO:
+                hQuery:GET-NEXT ().
+                NEXT.
+            END.
+            IF iCurrentPosition = 0 THEN iCurrentPosition = ii.
+            i1 = i1 + 1.
+            IF i1 <= iMaxRecords THEN 
+            DO:
+                httTable:BUFFER-CREATE().
+                httTable:BUFFER-COPY(hBuffer).
+            END.
+            hQuery:GET-NEXT ().
+        END.
+        hQuery:QUERY-CLOSE ().
+        DELETE OBJECT hBuffer NO-ERROR.
+
+        iPageCounter = ii / iMaxRecords.
+        IF (iPageCounter * iMaxRecords) < ii THEN iPageCounter = iPageCounter + 1.  
+        oRecords = NEW JsonArray().
+        httTable:WRITE-JSON('JsonArray', oRecords).
+
+        oJsonReturn = NEW JsonObject().
+        oJsonReturn:ADD('records'   , oRecords).
+        oJsonReturn:ADD('maxRecords', ii).
+        oJsonReturn:ADD('pageCount' , iPageCounter).
+        outilitiesHandler:writePosition(
+            INPUT  oJsonIdent       ,
+            INPUT  cFileName        ,
+            INPUT  iCurrentPosition 
+            ).
+        oJsonReturn:WriteFile('C:\TEMP\getData_messages.json', TRUE).
+        lRetVal = TRUE.        
+        RETURN lRetVal.
+
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD PUBLIC LOGICAL rebuildData(
+        INPUT  oJsonIdent  AS JsonObject,
+        OUTPUT oJsonReturn AS JsonObject  
+        ):
+        
+        DEFINE VARIABLE ii           AS INTEGER   NO-UNDO.
+        DEFINE VARIABLE i1           AS INTEGER   NO-UNDO.
+        DEFINE VARIABLE iNumerisch   AS INTEGER   NO-UNDO.
+        DEFINE VARIABLE lRetVal      AS LOGICAL   NO-UNDO.
+        DEFINE VARIABLE cSortField   AS CHARACTER NO-UNDO INIT ''.
+        DEFINE VARIABLE cSearchChars AS CHARACTER NO-UNDO INIT ''.
+        DEFINE VARIABLE cValue       AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE cDirection   AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE cFields      AS CHARACTER NO-UNDO EXTENT.
+        DEFINE VARIABLE cField       AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE cDBField     AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE cWhere       AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE cType        AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE lOK          AS LOGICAL   NO-UNDO.
+        DEFINE VARIABLE rBuffer      AS RECID     NO-UNDO.
+        
+        outilitiesHandler = NEW utilitiesHandler().
+
+        outilitiesHandler:evaluateFile(
+            INPUT  oJsonIdent   ,
+            OUTPUT cFileName    ,
+            OUTPUT lCompany     ,
+            OUTPUT lActive      ,
+            OUTPUT lWordindex
+            ).
+            
+        cFieldReplace    = SUBSTITUTE('&1_'         , cFileName).
+        cKeyFieldReplace = SUBSTITUTE('keyfield_&1_', cFileName).
+        cFilterReplace   = SUBSTITUTE('filter_&1_'  , cFileName).
+        
+        lOK = outilitiesHandler:getKeyFields(
+            INPUT  oJsonIdent   ,
+            OUTPUT cKeyFields   ,
+            OUTPUT cKeyValues
+            ).
+        
+        CREATE BUFFER hBuffer FOR TABLE cFileName.
+        
+        cuser_name = oJsonIdent:GetCharacter('user_name').
+        ccompany   = oJsonIdent:GetCharacter('company').
+        
+        cSortField   = ''.
+        cDirection   = ''.
+        cWhere       = ''.
+        cPrimaryKey  = ''.
+        iStartPage   = 1.
+        iStartRecord = 1. 
+        
+        IF lCompany THEN cWhere = SUBSTITUTE('WHERE &1.company = &2', cFileName, QUOTER(ccompany)).
+        IF cKeyFields <> '' THEN 
+        DO:
+            DO ii = 1 TO NUM-ENTRIES(cKeyFields, ';'):
+                cString = ENTRY(ii, cKeyFIelds, ';').
+                cString = REPLACE(cString, cKeyFieldReplace, '').
+                cString = REPLACE(cString, cFieldReplace, '').
+                IF cString = 'company' THEN NEXT.
+                cString = SUBSTITUTE('&1.&2 = &3 ', cFileName, cString, ENTRY(ii, cKeyValues, CHR(01))).
+                cPrimaryKey = cPrimaryKey + (IF cPrimaryKey = '' THEN 'WHERE ' ELSE 'AND ') + cString.
+            END.
+        END.
+        
+        outilitiesHandler:readStartcWhere(
+            INPUT  oJsonIdent,
+            INPUT  cFileName ,
+            OUTPUT cWhere
+            ).
+        
+        outilitiesHandler:readSortFields(
+            INPUT  oJsonIdent,
+            INPUT  cFileName ,
+            OUTPUT cSortField,
+            OUTPUT cDirection).
+        
+        IF cSortField <> '' THEN cWhere = cWhere + ' BY ' + cSortField + ' ' + cDirection.
+         
+        CREATE TEMP-TABLE ttTable.
+        ttTable:ADD-FIELDS-FROM (cFilename, 'wordindex').
+        IF cSortField <> '' THEN 
+        DO:
+            ttTable:ADD-NEW-INDEX   ('ttTable-k1', FALSE, TRUE).     /*  UNIQUE, PRIMARY */
+            ttTable:ADD-INDEX-FIELD ('ttTable-k1', cSortField, cDirection).
+        END.
+        ttTable:TEMP-TABLE-PREPARE ('records').
+        httTable = ttTable:DEFAULT-BUFFER-HANDLE.
+         
+        DO ii = 1 TO httTable:NUM-FIELDS:
+            httTable:BUFFER-FIELD(ii):SERIALIZE-NAME = cFileName + '_' + httTable:BUFFER-FIELD(ii):NAME NO-ERROR.
+        END.
+        MESSAGE 'cWhere beim Start des lesens ' cWhere.
+        ASSIGN 
+            ii               = 0
+            i1               = 0
+            iActualPage      = 0
+            iCurrentPosition = 0.
+        hBuffer:FIND-UNIQUE(cPrimaryKey, NO-LOCK) NO-ERROR.
+        rBuffer = hBuffer:RECID.
+        
+        ttTable:EMPTY-TEMP-TABLE ().
+        CREATE QUERY hQuery.
+        cWhere = SUBSTITUTE('FOR EACH &1 NO-LOCK &2 ', cFileName, cWhere) NO-ERROR.
+        hQuery:SET-BUFFERS (hBuffer) NO-ERROR.
+        hQuery:QUERY-PREPARE (cWhere) NO-ERROR.
+        hQuery:QUERY-OPEN ().
+        hQuery:GET-FIRST ().
+        MESSAGE 'cPrimaryKey = ' cPrimaryKey '- cWhere = ' cWhere.
+        lOK = FALSE.
+        DO WHILE NOT hQuery:QUERY-OFF-END:
+            ii = ii + 1.
+            IF ii < iStartRecord THEN 
+            DO:
+                hQuery:GET-NEXT ().
+                NEXT.
+            END.
+            IF  NOT lOK                AND
+                ii MOD iMaxRecords = 1 THEN iActualPage = iActualPage + 1.
+            IF NOT lOK THEN 
+            DO:
+                IF hBuffer:RECID <> rBuffer THEN 
+                DO:
+                    hQuery:GET-NEXT().
+                    NEXT.
+                END.
+                iIndex = ii MOD iMaxRecords.
+                iStartIndex = ii - iIndex + 1.
+                DO WHILE ii > iStartIndex:
+                    hQuery:GET-PREV ().
+                    ii = ii - 1.
+                END.
+                lOK = TRUE.
+            END.
+            IF iCurrentPosition = 0 THEN iCurrentPosition = ii.
+            i1 = i1 + 1.
+            IF i1 <= iMaxRecords THEN 
+            DO:
+                httTable:BUFFER-CREATE().
+                httTable:BUFFER-COPY(hBuffer).
+            END.
+            hQuery:GET-NEXT ().
+        END.
+        hQuery:QUERY-CLOSE ().
+        DELETE OBJECT hBuffer NO-ERROR.
+        
+        IF ii = 0 THEN RETURN FALSE.
+
+        iPageCounter = ii / iMaxRecords.
+        IF (iPageCounter * iMaxRecords) < ii THEN iPageCounter = iPageCounter + 1. 
+ 
+        oJsonPosition = NEW JsonObject().
+        oJsonPosition:ADD('page' , iActualPage).
+        oJsonPosition:ADD('index', iIndex - 1).     /* -1 weil in Java beginnt Index bei 0  */
+        
+        oRecords = NEW JsonArray().
+        httTable:WRITE-JSON('JsonArray', oRecords).
+        
+        oJsonReturn = NEW JsonObject().
+        oJsonReturn:ADD('records'   , oRecords).
+        oJsonReturn:ADD('maxRecords', ii).
+        oJsonReturn:ADD('pageCount' , iPageCounter).
+        oJsonReturn:ADD('position'  , oJsonPosition).
+        outilitiesHandler:writePosition(
+            INPUT  oJsonIdent       ,
+            INPUT  cFileName        ,
+            INPUT  iCurrentPosition 
+            ).
+            
+        lRetVal = TRUE.        
+        RETURN lRetVal.
+
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD PUBLIC LOGICAL updateData(
+        INPUT  oJsonIdent  AS JsonObject,
+        INPUT  oJsonRecord AS jsonObject,
+        OUTPUT oJsonReturn AS JsonObject  
+        ):
+    
+        DEFINE VARIABLE oJsonMessage  AS JsonObject NO-UNDO.
+        DEFINE VARIABLE oJsonPosition AS JsonObject NO-UNDO.
+
+        DEFINE VARIABLE lRetVal       AS LOGICAL    NO-UNDO.
+        DEFINE VARIABLE lOK           AS LOGICAL    NO-UNDO.
+        DEFINE VARIABLE ii            AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE i1            AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE iIndex        AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE cWordIndex    AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cSortField    AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cDirection    AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE hField        AS HANDLE     NO-UNDO.
+        DEFINE VARIABLE htField       AS HANDLE     NO-UNDO.
+        DEFINE VARIABLE cField        AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cValue        AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cIndexFields  AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE rBuffer       AS RECID      NO-UNDO.
+
+        outilitiesHandler = NEW utilitiesHandler().
+
+        outilitiesHandler:evaluateFile(
+            INPUT  oJsonIdent   ,
+            OUTPUT cFileName    ,
+            OUTPUT lCompany     ,
+            OUTPUT lActive      ,
+            OUTPUT lWordindex
+            ).
+            
+        cFieldReplace    = SUBSTITUTE('&1_', cFileName).
+        cKeyFieldReplace = SUBSTITUTE('keyfield_&1_', cFileName).
+        cFilterReplace   = SUBSTITUTE('filter_&1_', cFileName).
+        cFileReplace     = SUBSTITUTE('&1_', cFileName).
+        iLanguage_id     = oJsonIdent:GetInteger('language_id').
+        ccompany         = oJsonIdent:GetCharacter('company').
+
+        lOK = outilitiesHandler:getKeyFields(
+            INPUT  oJsonIdent   ,
+            OUTPUT cKeyFields   ,
+            OUTPUT cKeyValues
+            ).
+
+        CREATE TEMP-TABLE ttTable.
+        ttTable:ADD-FIELDS-FROM (cFileName, 'wordindex'). /*  except Field wordindex  */
+        ttTable:TEMP-TABLE-PREPARE ('record').
+        httTable = ttTable:DEFAULT-BUFFER-HANDLE.
+
+        DO ii = 1 TO httTable:NUM-FIELDS:
+            httTable:BUFFER-FIELD(ii):SERIALIZE-NAME = cFileName + '_' + httTable:BUFFER-FIELD(ii):NAME NO-ERROR.
+        END.
+
+        httTable:READ-JSON('JsonObject', oJsonRecord) NO-ERROR.
+        httTable:FIND-FIRST('', NO-LOCK).
+
+        //  Primary-Index-Fields für WHERE-Statement        
+        CREATE BUFFER hBuffer FOR TABLE cFileName.
+        cIndexFields = outilitiesHandler:getPrimaryIndexFields(
+            INPUT cFileName
+            ).
+
+        //  Erzeugen von Where-Statement für UNIQUE-Find
+        cWhere = ''.    
+        DO i1 = 1 TO NUM-ENTRIES(cIndexFields, ';'):
+            cField = ENTRY(i1, cIndexFields, ';').
+            hField = httTable:BUFFER-FIELD(cField):HANDLE.
+            CASE hField:DATA-TYPE:
+                WHEN 'character' THEN 
+                    cValue = QUOTER(hField:BUFFER-VALUE).
+                WHEN 'logical'   THEN 
+                    cValue = STRING(hField:BUFFER-VALUE,"TRUE/FALSE").
+                WHEN 'date'      THEN 
+                    cValue = STRING(DATE(hField:BUFFER-VALUE)).
+                OTHERWISE             
+                cValue = hField:BUFFER-VALUE. 
+            END CASE.
+            cWhere = cWhere
+                + (IF cWhere = '' THEN 'WHERE ' ELSE ' AND ')
+                + SUBSTITUTE('&1.&2 = ', cFileName, cField)
+                + cValue.
+        END.
+
+        lRetVal = FALSE.
+        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
+            lOK = hBuffer:FIND-UNIQUE(cWhere) NO-ERROR. 
+            IF NOT hBuffer:AVAILABLE THEN 
+            DO:
+                outilitiesHandler:getErrorMessage(
+                    INPUT  '1014',
+                    INPUT  ilanguage_id,
+                    INPUT  '',
+                    OUTPUT lcMessage).
+                LEAVE.
+            END.
+
+            DO ii = 1 TO httTable:NUM-FIELDS:
+                hField  = hBuffer:BUFFER-FIELD(ii):HANDLE NO-ERROR.
+                IF  ERROR-STATUS:ERROR       OR
+                    NOT VALID-HANDLE(hField) THEN NEXT.
+                    
+                htField = httTable:BUFFER-FIELD(ii):HANDLE NO-ERROR.
+                IF htField:BUFFER-VALUE = hField:BUFFER-VALUE THEN NEXT.
+                hField:BUFFER-VALUE = htField:BUFFER-VALUE. 
+            END.
+            
+            hField = hBuffer:BUFFER-FIELD('updated_at'):HANDLE NO-ERROR.
+            IF  NOT ERROR-STATUS:ERROR AND
+                VALID-HANDLE(hField)   THEN hField:BUFFER-VALUE = NOW.
+            
+            hField = hBuffer:BUFFER-FIELD('wordindex'):HANDLE NO-ERROR.
+            IF  NOT ERROR-STATUS:ERROR AND
+                VALID-HANDLE(hField)   THEN 
+            DO:
+                cWordIndex = outilitiesHandler:createWordindex(
+                    INPUT hBuffer
+                    ).
+                hField:BUFFER-VALUE = cWordIndex.
+            END.
+            rBuffer = hBuffer:RECID.
+            
+            oJsonReturn = NEW JsonObject().
+            oJsonData   = NEW JsonObject().
+            oJsonArray  = NEW JsonArray ().
+            httTable:BUFFER-COPY(hBuffer).
+            httTable:WRITE-JSON('JsonObject', oJsonData).
+    
+            oJsonArray = oJsonData:GetJsonArray('record').
+            oJsonData  = oJsonArray:GetJsonObject(1). 
+            oJsonReturn:ADD('record', oJsonData).
+            
+            hBuffer:BUFFER-RELEASE ().
+            
+            outilitiesHandler:readSortFields(
+                INPUT  oJsonIdent ,
+                INPUT  cFileName  ,
+                OUTPUT cSortField ,
+                OUTPUT cDirection ).
+
+            //  Where-Statement f�r FOR EACH Filename f�r die Anzeige            
+            cWhere  = ''.
+            IF lCompany THEN cWhere = SUBSTITUTE('WHERE &1.company = &2', cFileName, QUOTER(ccompany)).
+            IF cKeyFields <> '' THEN
+            DO:
+                DO ii = 1 TO NUM-ENTRIES(cKeyFields, ';'):
+                    cField = ENTRY(ii, cKeyFields, ';').
+                    cField = REPLACE(cField, cKeyFieldReplace, '').
+                    cField = REPLACE(cField, cFilterReplace, '').
+                    cField = REPLACE(cField, cFileReplace, '').
+                    IF  lCompany           AND 
+                        cField = 'company' THEN NEXT.
+                    cValue = ENTRY(ii, cKeyValues, CHR(01)).
+                    cWhere = cWhere
+                        + (IF cWhere = '' THEN 'WHERE &1.&2 = &3' ELSE ' AND &1.&2 = &3').
+                    cWhere = SUBSTITUTE(cWhere, cFileName, cField, cValue).
+                END.
+            END.
+            
+            CREATE QUERY hQuery.
+            hQuery:SET-BUFFERS (hBuffer).
+            cWhere = SUBSTITUTE('FOR EACH &1 NO-LOCK &2 ', cFileName, cWhere).
+            IF cSortField <> '' THEN cWhere = cWhere + ' BY ' + cSortField + ' ' + cDirection.
+
+            hQuery:QUERY-PREPARE(cWhere).
+            hQuery:QUERY-OPEN().
+            hQuery:GET-FIRST().
+            
+            ii = 0.
+            i1 = 0.  
+            DO WHILE NOT hQuery:QUERY-OFF-END:
+                ii = ii + 1.
+                IF hBuffer:RECID = rBuffer THEN i1 = ii.
+                hQuery:GET-NEXT ().
+            END.
+            hQuery:QUERY-CLOSE ().
+        
+            iPageCounter = i1 / iMaxRecords.
+            IF (iPageCounter * iMaxRecords) < i1 THEN iPageCounter = iPageCounter + 1.
+
+            iIndex = i1 MOD iMaxRecords.
+            IF iIndex = 0 THEN iIndex = iMaxRecords.
+                          
+            oJsonPosition = NEW JsonObject().
+            oJsonPosition:ADD('page', iPageCounter).
+            oJsonPosition:ADD('index', iIndex - 1).     /* -1 weil in Java beginnt Index bei 0  */
+            oJsonPosition:ADD('totalRecords', ii).
+            
+            oJsonReturn:ADD('position', oJsonPosition).
+
+            lRetVal = TRUE.
+            LEAVE.
+        END.
+        
+        IF NOT lRetVal THEN 
+        DO:
+            oJsonMessage = NEW JsonObject().
+            oJsonMessage:ADD('success', FALSE).
+            oJsonMessage:ADD('message', lcMessage).
+            oJsonMessage:WRITE(lcJsonString, FALSE).
+            
+            oJsonReturn = oJsonMessage.
+        END.
+        
+        RETURN lRetVal.
+
+        CATCH e AS Progress.Lang.Error:
+
+        END CATCH.
+
+        FINALLY:
+
+        END FINALLY.
+
+    END METHOD.
+
+    DESTRUCTOR PUBLIC adminprogsHandler ( ):
+
+    END DESTRUCTOR.
+
+END CLASS.

+ 814 - 0
admin/dynamicformImpl.cls

@@ -0,0 +1,814 @@
+/*------------------------------------------------------------------------
+   File        : dynamicformImplImpl
+   Purpose     : 
+   Syntax      : 
+   Description : 
+   Author(s)   : walter.riechsteiner
+   Created     : Wed Nov 19 13:23:38 CET 2025
+   Notes       : 
+ ----------------------------------------------------------------------*/
+
+
+BLOCK-LEVEL ON ERROR UNDO, THROW.
+
+USING OpenEdge.Core.String                          FROM PROPATH.
+USING OpenEdge.Net.HTTP.IHttpResponse               FROM PROPATH.
+USING OpenEdge.Net.HTTP.StatusCodeEnum              FROM PROPATH.
+USING OpenEdge.Web.IWebRequest                      FROM PROPATH.
+USING OpenEdge.Web.WebResponseWriter                FROM PROPATH.
+USING OpenEdge.Web.WebHandler                       FROM PROPATH.
+
+USING Progress.Json.ObjectModel.ObjectModelParser   FROM PROPATH.
+USING Progress.Json.ObjectModel.JsonObject          FROM PROPATH.
+USING Progress.Json.ObjectModel.JsonArray           FROM PROPATH.
+
+USING src.ch.adprime.gemis.WebHandlerUtilities      FROM PROPATH.
+USING utilities.selectboxHandler                    FROM PROPATH.
+USING utilities.utilitiesHandler                    FROM PROPATH.
+USING admin.usersHandler                            FROM PROPATH.
+USING admin.adminprogsHandler                       FROM PROPATH.
+
+CLASS admin.dynamicformImpl INHERITS WebHandler: 
+
+    DEFINE VARIABLE oResponse         AS IHttpResponse        NO-UNDO.         
+    DEFINE VARIABLE oWriter           AS WebResponseWriter    NO-UNDO.
+    DEFINE VARIABLE oBody             AS String               NO-UNDO.
+    DEFINE VARIABLE cDefautlCharSet   AS CHARACTER            NO-UNDO INIT 'UTF-8'.
+    DEFINE VARIABLE oParser           AS ObjectModelParser    NO-UNDO.           
+    DEFINE VARIABLE cCorralationID    AS CHARACTER            NO-UNDO.
+    DEFINE VARIABLE cContent-Type     AS CHARACTER            NO-UNDO.
+    DEFINE VARIABLE lcJsonString      AS LONGCHAR             NO-UNDO.
+    
+    DEFINE VARIABLE oHandler          AS Progress.Lang.Object NO-UNDO.
+    DEFINE VARIABLE cMethode          AS CHARACTER            NO-UNDO.
+    
+    DEFINE VARIABLE ccompany          AS CHARACTER            NO-UNDO.
+    DEFINE VARIABLE cuser_name        AS CHARACTER            NO-UNDO.
+    DEFINE VARIABLE cAnzeigeName      AS CHARACTER            NO-UNDO.
+    DEFINE VARIABLE ilanguage_id      AS INTEGER              NO-UNDO.
+    DEFINE VARIABLE cSessionToken     AS CHARACTER            NO-UNDO.
+    DEFINE VARIABLE cFunction         AS CHARACTER            NO-UNDO.
+    DEFINE VARIABLE cForm_Id          AS CHARACTER            NO-UNDO.
+    DEFINE VARIABLE cProgram          AS CHARACTER            NO-UNDO.
+    DEFINE VARIABLE cProgramUser      AS CHARACTER            NO-UNDO.
+    DEFINE VARIABLE cUsers            AS CHARACTER            NO-UNDO INIT 'user,admin'.
+    DEFINE VARIABLE lcMessage         AS LONGCHAR             NO-UNDO.
+    DEFINE VARIABLE cErrorNo          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 outilitiesHandler AS utilitiesHandler     NO-UNDO.
+    DEFINE VARIABLE oselectboxHandler AS selectboxHandler     NO-UNDO.
+
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleDelete(INPUT poRequest AS IWebRequest):
+        
+        DEFINE VARIABLE oJsonResponse AS JsonObject NO-UNDO.
+        DEFINE VARIABLE oJsonIdent    AS JsonObject NO-UNDO.
+        DEFINE VARIABLE oJsonBox      AS JsonArray  NO-UNDO.
+        DEFINE VARIABLE oJsonData     AS JsonObject NO-UNDO.
+        
+        DEFINE VARIABLE lRetVal       AS LOGICAL    NO-UNDO.
+        DEFINE VARIABLE ii            AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE i1            AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE cQueryString  AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cQueryPairs   AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cQueryKey     AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cQueryValue   AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cFileName     AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cFieldName    AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cClassName    AS CHARACTER  NO-UNDO.
+        
+        DEFINE VARIABLE oJsonResult   AS JsonObject NO-UNDO.
+        DEFINE VARIABLE oJsonMessage  AS JsonObject NO-UNDO.
+        DEFINE VARIABLE httBuffer     AS HANDLE     NO-UNDO.
+
+        lRetVal = WebHandlerUtilities:getJsonFromRequest(INPUT poRequest, OUTPUT oJsonData) NO-ERROR.
+
+        outilitiesHandler = NEW utilitiesHandler().
+        
+        outilitiesHandler:getHeaderData(
+            INPUT  poRequest    ,
+            OUTPUT ccompany     ,
+            OUTPUT cuser_name   ,
+            OUTPUT cAnzeigeName ,
+            OUTPUT ilanguage_id ,
+            OUTPUT cSessionToken
+            ).
+
+        oJsonIdent = NEW JsonObject().
+        oJsonIdent:ADD('company'     , ccompany     )   NO-ERROR.
+        oJsonIdent:ADD('user_name'   , cuser_name   )   NO-ERROR.
+        oJsonIdent:ADD('language_id' , iLanguage_id )   NO-ERROR.
+        oJsonIdent:ADD('sessionToken', cSessionToken)   NO-ERROR.
+        
+        cQueryString = STRING(poRequest:GetContextValue("QUERY_STRING"))    NO-ERROR.
+        DO ii = 1 TO NUM-ENTRIES(cQueryString, '&'):
+            cQueryPairs = ENTRY(ii, cQueryString, '&').
+            cQueryKey   = ENTRY(1 , cQueryPairs , '=').
+            cQueryValue = ENTRY(2 , cQueryPairs , '=').
+            IF oJsonIdent:Has(cQueryKey) THEN oJsonIdent:SET(cQueryKey, cQueryValue) NO-ERROR.
+            ELSE                              oJsonIdent:ADD(cQueryKey, cQueryValue) NO-ERROR.
+        END.
+        MESSAGE 'dynamic DELETE' STRING(oJsonIdent:GetJsonText()).        
+        cClassName = ENTRY(1, cForm_Id, '_').
+        
+        lRetVal  = FALSE.
+        
+        cuser_name = oJsonIdent:GetCharacter('H_user_name') NO-ERROR.
+        IF LOOKUP(cuser_name, cUsers, ',') = 0 THEN cUsers = cuser_name + ',' + cUsers.
+        cuser_name = oJsonIdent:GetCharacter('user_name') NO-ERROR.
+        IF LOOKUP(cuser_name, cUsers, ',') = 0 THEN cUsers = cuser_name + ',' + cUsers.
+        cProgram = outilitiesHandler:getProgramName (
+            INPUT  oJsonIdent,
+            INPUT  cUsers
+            ).
+            
+        cFunction = oJsonIdent:GetCharacter('function').
+
+        REPEAT TRANSACTION WHILE cFunction = 'delete' ON ERROR UNDO, LEAVE:
+            
+            DEFINE VARIABLE cClass     AS CHARACTER                   NO-UNDO.
+            DEFINE VARIABLE rClass     AS Progress.Lang.Class.
+            DEFINE VARIABLE rParamList AS Progress.Lang.ParameterList.
+            
+            CASE cClassName:
+                WHEN 'users'    THEN 
+                    cClass = 'admin.usersHandler'. 
+                WHEN 'messages' THEN 
+                    cClass = 'admin.adminprogsHandler'. 
+                WHEN 'labeltexte' THEN 
+                    cClass = 'admin.adminprogsHandler'. 
+            END CASE.
+            
+            ASSIGN
+                rClass = Progress.Lang.Class:GetClass(cClass).
+            oHandler = rClass:NEW().
+            /*            CASE cClassName:                           */
+            /*                WHEN 'users' THEN                      */
+            /*                    oHandler = NEW usersHandler().     */
+            /*                WHEN 'messages' THEN                   */
+            /*                    oHandler = NEW adminprogsHandler().*/
+            /*            END CASE.                                  */
+
+            cMethode = 'deleteData'.
+
+            oHandler = rClass:NEW().
+            lRetVal = DYNAMIC-INVOKE ( oHandler, cMethode,
+                INPUT  oJsonIdent  ,
+                INPUT  oJsonData   ,
+                OUTPUT oJsonResult
+                ).
+            IF NOT lRetVal THEN LEAVE.
+            
+            oJsonResult:WRITE(lcJsonString, FALSE).
+            LEAVE.
+        END.
+                    
+        oResponse             = NEW OpenEdge.Web.WebResponse().
+        oResponse:StatusCode  = INTEGER(StatusCodeEnum:OK).
+        oResponse:ContentType = "application/json;charset=utf-8".
+        oWriter               = NEW WebResponseWriter(oResponse).
+                        
+        IF NOT lRetVal THEN 
+        DO:
+            oJsonMessage = NEW JsonObject().
+            oJsonMessage:ADD('success', FALSE).
+            oJsonMessage:ADD('message', 'Fehler beim create/POST des Users').
+            oJsonMessage:WRITE(lcJsonString, FALSE).
+        END.
+                            
+        oWriter:Open().
+        oWriter:Write(lcJsonString).
+        oWriter:Close().
+    
+        RETURN 0.
+    
+        CATCH e AS Progress.Lang.Error:
+                
+        END CATCH.
+                
+        FINALLY:
+        /*            DELETE OBJECT oJsonConfig. */
+        /*            DELETE OBJECT oJsonMessage.*/
+        END FINALLY.
+
+    END METHOD.
+    
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleGet (INPUT poRequest AS IWebRequest ):
+        
+        DEFINE VARIABLE oJsonResponse    AS JsonObject NO-UNDO.
+        DEFINE VARIABLE oJsonIdent       AS JsonObject NO-UNDO.
+        DEFINE VARIABLE oJsonSelectBoxes AS JsonObject NO-UNDO.
+        DEFINE VARIABLE oJsonBox         AS JsonArray  NO-UNDO.
+        
+        DEFINE VARIABLE lRetVal          AS LOGICAL    NO-UNDO.
+        DEFINE VARIABLE ii               AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE i1               AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE cQueryString     AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cQueryPairs      AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cQueryKey        AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cQueryValue      AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cFileName        AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cFieldName       AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cClassName       AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cActiveSelection AS CHARACTER  NO-UNDO.
+        
+        DEFINE VARIABLE oJsonResult      AS JsonObject NO-UNDO.
+        DEFINE VARIABLE httBuffer        AS HANDLE     NO-UNDO.
+        
+        outilitiesHandler = NEW utilitiesHandler().
+        
+        outilitiesHandler:getHeaderData(
+            INPUT  poRequest    ,
+            OUTPUT ccompany     ,
+            OUTPUT cuser_name   ,
+            OUTPUT cAnzeigeName ,
+            OUTPUT ilanguage_id ,
+            OUTPUT cSessionToken
+            ).
+        
+        oJsonIdent = NEW JsonObject().
+        oJsonIdent:ADD('H_company'     , ccompany     )   NO-ERROR.
+        oJsonIdent:ADD('H_user_name'   , cuser_name   )   NO-ERROR.
+        oJsonIdent:ADD('H_display_name', cAnzeigeName )   NO-ERROR.
+        oJsonIdent:ADD('H_language_id' , iLanguage_id )   NO-ERROR.
+        oJsonIdent:ADD('H_sessionToken', cSessionToken)   NO-ERROR.
+        //
+        //  Alle Parameter aus dem Query-String lesen und im Object oJsonIdent ergänzenz
+        //
+        cQueryString = STRING(poRequest:GetContextValue("QUERY_STRING"))    NO-ERROR.
+        DO ii = 1 TO NUM-ENTRIES(cQueryString, '&'):
+            cQueryPairs = ENTRY(ii, cQueryString, '&').
+            cQueryKey   = ENTRY(1 , cQueryPairs , '=').
+            cQueryValue = ENTRY(2 , cQueryPairs , '=').
+            IF oJsonIdent:Has(cQueryKey) THEN oJsonIdent:SET(cQueryKey, cQueryValue) NO-ERROR.
+            ELSE                              oJsonIdent:ADD(cQueryKey, cQueryValue) NO-ERROR.
+        END.
+        //
+        //  mögliche Benutzer für das durchsuchen von HTML-DOkumenten und Labeltexten ...
+        //
+        cuser_name = oJsonIdent:GetCharacter('H_user_name') NO-ERROR.
+        IF NOT ERROR-STATUS:ERROR AND LOOKUP(cuser_name, cUsers, ',') = 0 THEN cUsers = cuser_name + ',' + cUsers.
+        cuser_name = oJsonIdent:GetCharacter('user_name') NO-ERROR.
+        IF NOT ERROR-STATUS:ERROR AND LOOKUP(cuser_name, cUsers, ',') = 0 THEN cUsers = cuser_name + ',' + cUsers.
+        
+        lRetVal = FALSE.
+
+        MASTERLOOP:
+        DO WHILE TRUE:
+            //
+            //  Programmname aus den möglichen Benutzern ermitteln
+            //
+            cProgram = outilitiesHandler:getProgramName (
+                INPUT  oJsonIdent,
+                INPUT  cUsers
+                ).
+MESSAGE 'getProgramName ' cProgram.
+            IF cProgram = '' THEN 
+            DO:
+                outilitiesHandler:getErrorMessage(
+                    INPUT  '1000',
+                    INPUT  oJsonIdent:GetInteger('language_id'),
+                    INPUT  '',  /* Parameters */
+                    OUTPUT lcMessage
+                    ).
+                LEAVE.
+            END.            
+            oJsonIdent:ADD('program', cProgram).
+            
+            cErrorNo = ''.
+            cForm_Id = oJsonIdent:GetCharacter("formId") NO-ERROR.
+            IF NOT ERROR-STATUS:ERROR THEN 
+            DO:
+                cClassName = ENTRY(1, cForm_Id, '_').
+                cFileName  = ENTRY(1, cForm_Id, '_').
+            END.
+            IF  cClassName = '' THEN
+                cErrorNo = cErrorNo 
+                    + (IF cErrorNo = '' THEN '' ELSE ',')
+                    + '1001'.
+            IF cFileName = '' THEN
+                cErrorNo = cErrorNo 
+                    + (IF cErrorNo = '' THEN '' ELSE ',')
+                    + '1002'.
+            IF cErrorNo <> '' THEN 
+            DO:
+                outilitiesHandler:getErrorMessage(
+                    INPUT  cErrorNo,
+                    INPUT  oJsonIdent:GetInteger('language_id'),
+                    INPUT  '',  /* Parameters */
+                    OUTPUT lcMessage
+                    ).
+                LEAVE.
+            END.
+            oJsonIdent:ADD('class_name', cClassName).
+            oJsonIdent:ADD('file_name' , cFileName ).
+            
+            IF NOT oJsonIdent:HAS('company'    ) THEN oJsonIdent:ADD('company'    , oJsonIdent:GetCharacter('H_company'    )).
+            IF NOT oJsonIdent:HAS('user_name'  ) THEN oJsonIdent:ADD('user_name'  , oJsonIdent:GetCharacter('H_user_name'  )).
+            IF NOT oJsonIdent:HAS('language_id') THEN oJsonIdent:ADD('language_id', oJsonIdent:GetInteger  ('H_language_id')).
+        
+            oJsonIdent:WriteFile('C:\TEMP\dynamicform_GET.json', TRUE).
+        
+            cFunction = oJsonIdent:GetCharacter('function').
+            cCompany  = oJsonIdent:GetCharacter('company').
+     
+            DO WHILE cFunction = 'init' AND cProgram <> '':
+            
+                FIND FIRST selectboxfields NO-LOCK
+                    WHERE selectboxfields.company = ccompany
+                    AND   selectboxfields.program = cform_id NO-ERROR.
+                IF NOT AVAILABLE selectboxfields THEN LEAVE.
+
+                oselectboxHandler = NEW selectboxHandler().
+                oJsonSelectBoxes  = NEW JsonObject().
+                FOR EACH selectboxfields NO-LOCK
+                    WHERE selectboxfields.company = ccompany
+                    AND   selectboxfields.program = cform_id:
+
+                    DO ii = 1 TO NUM-ENTRIES(selectboxfields.boxfields, ';'):
+                        cFieldName = ENTRY(ii, selectboxfields.boxfields, ';').
+                        cFileName  = ENTRY(1, cFieldName, '_').
+
+                        IF cFieldName MATCHES('*company*') THEN 
+                        DO:
+                            oJsonBox  = NEW JsonArray().
+                            httBuffer = oSelectboxHandler:getSelboxCompany(INPUT cFileName).
+                            httBuffer:WRITE-JSON ('JsonArray', oJsonBox).
+                            oJsonSelectBoxes:ADD(cFieldName, oJsonBox).
+                            NEXT.
+                        END.
+            
+                        IF cFieldName MATCHES('*language_id*') THEN 
+                        DO:
+                            oJsonBox  = NEW JsonArray().
+                            httBuffer = oSelectboxHandler:getSelboxLanguage(INPUT cFileName).
+                            httBuffer:WRITE-JSON ('JsonArray', oJsonBox).
+                            oJsonSelectBoxes:ADD(cFieldName, oJsonBox).
+                            NEXT.
+                        END.
+                    
+                        IF cFieldName MATCHES('*user_name*') THEN 
+                        DO:
+                            oJsonBox  = NEW JsonArray().
+                            httBuffer = oSelectboxHandler:getSelboxUsers(INPUT cFileName).
+                            httBuffer:WRITE-JSON ('JsonArray', oJsonBox).
+                            oJsonSelectBoxes:ADD(cFieldName, oJsonBox).
+                            NEXT.
+                        END.
+                    
+                        IF cFieldName MATCHES('*table_name*') THEN 
+                        DO:
+                            oJsonBox  = NEW JsonArray().
+                            httBuffer = oSelectboxHandler:getSelboxTables(INPUT cFileName).
+                            httBuffer:WRITE-JSON ('JsonArray', oJsonBox).
+                            oJsonSelectBoxes:ADD(cFieldName, oJsonBox).
+                            NEXT.
+                        END.
+                    
+                    END.
+                END.
+            
+                outilitiesHandler:evaluateFile(
+                    INPUT  oJsonIdent   ,
+                    OUTPUT cFileName    ,
+                    OUTPUT lCompany     ,
+                    OUTPUT lActive      ,
+                    OUTPUT lWordindex
+                    ).
+            
+                outilitiesHandler:getActiveSelection(
+                    INPUT  oJsonIdent      ,
+                    INPUT  cFileName       ,
+                    OUTPUT cActiveSelection
+                    ).
+            
+                oJsonResponse = NEW JsonObject().
+                oJsonResponse:ADD('selectOptionsFix', oJsonSelectBoxes).
+                oJsonResponse:ADD("activeFilter"    , cActiveSelection).
+                oJsonResponse:ADD("hasActiveField"  , lActive         ).
+                oJsonResponse:ADD("tableMaxHeight"  , '400px'         ).
+                oJsonResponse:ADD("itemsPerPage"    , 25              ).
+                oJsonResponse:WriteFile('C:\Temp\Dynamic_Init_response.json', TRUE).
+                lRetVal = TRUE.                
+                LEAVE. 
+            END.
+            
+            DO WHILE cFunction = 'loaddata' AND cProgram <> '':
+                CASE cClassName:
+                    WHEN 'users' THEN 
+                        oHandler = NEW usersHandler().
+                    WHEN 'messages' THEN 
+                        oHandler = NEW adminprogsHandler().
+                    WHEN 'labeltexte' THEN 
+                        oHandler = NEW adminprogsHandler().
+                END CASE.
+
+                cMethode = 'getData'.
+
+                lRetVal = DYNAMIC-INVOKE ( oHandler, cMethode,
+                    INPUT  oJsonIdent    ,
+                    OUTPUT oJsonResult
+                    ).
+            // oJsonResult:WriteFile('C:\TEMP\loaddate_result.json', TRUE).
+ 
+                oJsonResponse = NEW JsonObject().
+                oJsonResponse:ADD('selectOptionsFix', oJsonSelectBoxes).
+            
+                oJsonResponse = oJsonResult.
+
+                lRetVal = TRUE.
+                LEAVE.
+            END.
+        
+            DO WHILE cFunction = 'change' AND cProgram <> '':
+
+                CASE cClassName:
+                    WHEN 'users' THEN 
+                        oHandler = NEW usersHandler().
+                    WHEN 'messages' THEN 
+                        oHandler = NEW adminprogsHandler().
+                    WHEN 'labeltexte' THEN 
+                        oHandler = NEW adminprogsHandler().
+                END CASE.
+
+                cMethode = 'getChanges'.
+
+                lRetVal = DYNAMIC-INVOKE ( oHandler, cMethode,
+                    INPUT  oJsonIdent    ,
+                    OUTPUT oJsonResult
+                    ).
+            
+                oJsonResponse = NEW JsonObject().
+                oJsonResponse:ADD('selectOptionsFix', oJsonSelectBoxes).
+            
+                oJsonResponse = oJsonResult.
+
+                lRetVal = TRUE.
+                LEAVE.
+            END.
+        
+            DO WHILE cFunction = 'rebuild':
+            
+                CASE cClassName:
+                    WHEN 'users' THEN 
+                        oHandler = NEW usersHandler().
+                    WHEN 'messages' THEN 
+                        oHandler = NEW adminprogsHandler().
+                    WHEN 'labeltexte' THEN 
+                        oHandler = NEW adminprogsHandler().
+                END CASE.
+
+                cMethode = 'rebuildData'.
+
+                lRetVal = DYNAMIC-INVOKE ( oHandler, cMethode,
+                    INPUT  oJsonIdent    ,
+                    OUTPUT oJsonResult
+                    ).
+                IF NOT lRetVal THEN 
+                DO:
+                    outilitiesHandler:getErrorMessage(
+                        INPUT  '900'        ,
+                        INPUT  ilanguage_id ,
+                        INPUT   '',
+                        OUTPUT lcMessage).                    
+                    oJsonResponse = NEW JsonObject().
+                    oJsonResponse:ADD('success', FALSE).
+                    oJsonResponse:ADD('message', lcMessage).
+                    oJsonResponse:WRITE(lcJsonString, FALSE).
+                END.
+            
+                oJsonResponse = NEW JsonObject().
+                oJsonResponse:ADD('selectOptionsFix', oJsonSelectBoxes).
+            
+                oJsonResponse = oJsonResult.
+
+                lRetVal = TRUE.
+                LEAVE.
+            END.
+        
+            DO WHILE cFunction = 'saveActiveFilter':
+                cActiveSelection = oJsonIdent:GetCharacter('activeFilter').
+                outilitiesHandler:setActiveSelection(
+                    INPUT  oJsonIdent      ,
+                    INPUT  cFileName       ,
+                    INPUT  cActiveSelection
+                    ).
+            
+                oJsonResponse = NEW JsonObject().
+                oJsonResponse:ADD('success', TRUE).
+                oJsonResponse:WRITE(lcJsonString, FALSE).
+            
+                lRetVal = TRUE.
+                LEAVE.
+            END.
+        
+        // oJsonResponse:WriteFile('C:\Temp\dynamicform_response.json').
+            oJsonResponse:WRITE(lcJsonString, FALSE).
+        
+            LEAVE.
+        END.
+
+        IF NOT lRetVal THEN 
+        DO:
+            oJsonResponse = NEW JsonObject().
+            oJsonResponse:ADD('success', FALSE).
+            oJsonResponse:WRITE(lcJsonString, FALSE).
+        END.
+                
+        cContent-Type   = "application/json".
+        cDefautlCharSet = 'utf-8'.
+
+        oBody = NEW STRING(lcJsonString).
+        WebHandlerUtilities:createHttpResponse(INPUT INTEGER(StatusCodeEnum:OK), INPUT oBody, INPUT cContent-Type, INPUT cDefautlCharSet, INPUT cCorralationID, OUTPUT oResponse).
+//        oResponse:SetHeader(HttpHeaderBuilder:Build(cHeaderCorralationID):Value(cCorralationID):Header).
+
+        
+        oWriter = NEW WebResponseWriter(oResponse).
+        oWriter:Open(). 
+        oWriter:Close(). 
+
+        RETURN 0.
+        
+        CATCH e AS Progress.Lang.Error:
+
+        END CATCH.
+
+        FINALLY:
+
+        END FINALLY.
+
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD OVERRIDE PROTECTED INTEGER HandlePost(INPUT poRequest AS IWebRequest):
+        
+        DEFINE VARIABLE oJsonResponse AS JsonObject NO-UNDO.
+        DEFINE VARIABLE oJsonIdent    AS JsonObject NO-UNDO.
+        DEFINE VARIABLE oJsonBox      AS JsonArray  NO-UNDO.
+        DEFINE VARIABLE oJsonData     AS JsonObject NO-UNDO.
+        
+        DEFINE VARIABLE lRetVal       AS LOGICAL    NO-UNDO.
+        DEFINE VARIABLE ii            AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE i1            AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE cQueryString  AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cQueryPairs   AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cQueryKey     AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cQueryValue   AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cFileName     AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cFieldName    AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cClassName    AS CHARACTER  NO-UNDO.
+        
+        DEFINE VARIABLE oJsonResult   AS JsonObject NO-UNDO.
+        DEFINE VARIABLE oJsonMessage  AS JsonObject NO-UNDO.
+        DEFINE VARIABLE httBuffer     AS HANDLE     NO-UNDO.
+        
+        lRetVal = WebHandlerUtilities:getJsonFromRequest(INPUT poRequest, OUTPUT oJsonData) NO-ERROR.
+
+        outilitiesHandler = NEW utilitiesHandler().
+        
+        outilitiesHandler:getHeaderData(
+            INPUT  poRequest    ,
+            OUTPUT ccompany     ,
+            OUTPUT cuser_name   ,
+            OUTPUT cAnzeigeName ,
+            OUTPUT ilanguage_id ,
+            OUTPUT cSessionToken
+            ).
+
+        oJsonIdent = NEW JsonObject().
+        oJsonIdent:ADD('H_company'     , ccompany     )   NO-ERROR.
+        oJsonIdent:ADD('H_user_name'   , cuser_name   )   NO-ERROR.
+        oJsonIdent:ADD('H_display_name', cAnzeigeName )   NO-ERROR.
+        oJsonIdent:ADD('H_language_id' , iLanguage_id )   NO-ERROR.
+        oJsonIdent:ADD('H_sessionToken', cSessionToken)   NO-ERROR.
+        //
+        //  Alle Parameter aus dem Query-String lesen und im Object oJsonIdent ergänzenz
+        //
+        cQueryString = STRING(poRequest:GetContextValue("QUERY_STRING"))    NO-ERROR.
+        DO ii = 1 TO NUM-ENTRIES(cQueryString, '&'):
+            cQueryPairs = ENTRY(ii, cQueryString, '&').
+            cQueryKey   = ENTRY(1 , cQueryPairs , '=').
+            cQueryValue = ENTRY(2 , cQueryPairs , '=').
+            IF oJsonIdent:Has(cQueryKey) THEN oJsonIdent:SET(cQueryKey, cQueryValue) NO-ERROR.
+            ELSE                              oJsonIdent:ADD(cQueryKey, cQueryValue) NO-ERROR.
+        END.
+        
+        lRetVal  = FALSE.
+        cProgram = outilitiesHandler:getProgramName (
+            INPUT  oJsonIdent,
+            INPUT  cUsers
+            ).
+            
+        cFunction = oJsonIdent:GetCharacter('function').
+
+        REPEAT TRANSACTION WHILE cFunction = 'create' ON ERROR UNDO, LEAVE:
+            
+            CASE cClassName:
+                WHEN 'users' THEN 
+                    oHandler = NEW usersHandler().
+                WHEN 'messages' THEN 
+                    oHandler = NEW adminprogsHandler().
+                WHEN 'labeltexte' THEN 
+                    oHandler = NEW adminprogsHandler().
+            END CASE.
+
+            cMethode = 'createData'.
+
+            lRetVal = DYNAMIC-INVOKE ( oHandler, cMethode,
+                INPUT  oJsonIdent  ,
+                INPUT  oJsonData   ,
+                OUTPUT oJsonResult
+                ).
+            IF NOT lRetVal THEN LEAVE.
+            
+            oJsonResult:WRITE(lcJsonString, FALSE).
+            LEAVE.
+        END.
+                    
+        oResponse             = NEW OpenEdge.Web.WebResponse().
+        oResponse:StatusCode  = INTEGER(StatusCodeEnum:OK).
+        oResponse:ContentType = "application/json;charset=utf-8".
+        oWriter               = NEW WebResponseWriter(oResponse).
+                        
+        IF NOT lRetVal THEN 
+        DO:
+            oJsonMessage = NEW JsonObject().
+            oJsonMessage:ADD('success', FALSE).
+            oJsonMessage:ADD('message', oJsonResult:GetLongchar('message')).
+            oJsonMessage:WRITE(lcJsonString, FALSE).
+        END.
+        MESSAGE 'Rueckmeldung beim POST (CREATE) ' STRING(lcJsonString).
+                            
+        oWriter:Open().
+        oWriter:Write(lcJsonString).
+        oWriter:Close().
+    
+        RETURN 0.
+    
+        CATCH e AS Progress.Lang.Error:
+                
+        END CATCH.
+                
+        FINALLY:
+        /*            DELETE OBJECT oJsonConfig. */
+        /*            DELETE OBJECT oJsonMessage.*/
+        END FINALLY.
+
+    END METHOD.
+    
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD OVERRIDE PROTECTED INTEGER HandlePatch(INPUT poRequest AS IWebRequest):
+        
+        DEFINE VARIABLE oJsonResponse AS JsonObject NO-UNDO.
+        DEFINE VARIABLE oJsonIdent    AS JsonObject NO-UNDO.
+        DEFINE VARIABLE oJsonBox      AS JsonArray  NO-UNDO.
+        DEFINE VARIABLE oJsonData     AS JsonObject NO-UNDO.
+        
+        DEFINE VARIABLE lRetVal       AS LOGICAL    NO-UNDO.
+        DEFINE VARIABLE ii            AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE i1            AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE cQueryString  AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cQueryPairs   AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cQueryKey     AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cQueryValue   AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cFileName     AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cFieldName    AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cClassName    AS CHARACTER  NO-UNDO.
+        
+        DEFINE VARIABLE oJsonResult   AS JsonObject NO-UNDO.
+        DEFINE VARIABLE oJsonMessage  AS JsonObject NO-UNDO.
+        DEFINE VARIABLE httBuffer     AS HANDLE     NO-UNDO.
+        
+        lRetVal = WebHandlerUtilities:getJsonFromRequest(INPUT poRequest, OUTPUT oJsonData) NO-ERROR.
+        
+        outilitiesHandler = NEW utilitiesHandler().
+        
+        outilitiesHandler:getHeaderData(
+            INPUT  poRequest    ,
+            OUTPUT ccompany     ,
+            OUTPUT cuser_name   ,
+            OUTPUT cAnzeigeName ,
+            OUTPUT ilanguage_id ,
+            OUTPUT cSessionToken
+            ).
+
+        oJsonIdent = NEW JsonObject().
+        oJsonIdent:ADD('company'     , ccompany     )   NO-ERROR.
+        oJsonIdent:ADD('user_name'   , cuser_name   )   NO-ERROR.
+        oJsonIdent:ADD('language_id' , iLanguage_id )   NO-ERROR.
+        oJsonIdent:ADD('sessionToken', cSessionToken)   NO-ERROR.
+        
+        cQueryString = STRING(poRequest:GetContextValue("QUERY_STRING"))    NO-ERROR.
+        DO ii = 1 TO NUM-ENTRIES(cQueryString, '&'):
+            cQueryPairs = ENTRY(ii, cQueryString, '&').
+            cQueryKey   = ENTRY(1 , cQueryPairs , '=').
+            cQueryValue = ENTRY(2 , cQueryPairs , '=').
+            IF oJsonIdent:Has(cQueryKey) THEN oJsonIdent:SET(cQueryKey, cQueryValue) NO-ERROR.
+            ELSE                              oJsonIdent:ADD(cQueryKey, cQueryValue) NO-ERROR.
+        END.
+        MESSAGE 'dynamic PATCH' STRING(oJsonIdent:GetJsonText()).
+        cForm_Id   = poRequest:URI:GetQueryValue("formId") NO-ERROR.
+        cClassName = ENTRY(1, cForm_Id, '_').
+        
+        lRetVal  = FALSE.
+        cProgram = outilitiesHandler:getProgramName (
+            INPUT  oJsonIdent,
+            INPUT  cUsers
+            ).
+            
+        cFunction = oJsonIdent:GetCharacter('function').
+        
+        REPEAT TRANSACTION WHILE cFunction = 'update' ON ERROR UNDO, LEAVE:
+            
+            CASE cClassName:
+                WHEN 'users' THEN 
+                    oHandler = NEW usersHandler().
+                WHEN 'messages' THEN 
+                    oHandler = NEW adminprogsHandler().
+                WHEN 'labeltexte' THEN 
+                    oHandler = NEW adminprogsHandler().
+            END CASE.
+
+            cMethode = 'updateData'.
+
+            lRetVal = DYNAMIC-INVOKE ( oHandler, cMethode,
+                INPUT  oJsonIdent  ,
+                INPUT  oJsonData   ,
+                OUTPUT oJsonResult
+                ).
+            
+            oJsonResult:WRITE(LcJsonString, FALSE).
+            LEAVE.
+        END.
+                    
+        oResponse             = NEW OpenEdge.Web.WebResponse().
+        oResponse:StatusCode  = INTEGER(StatusCodeEnum:OK).
+        oResponse:ContentType = "application/json;charset=utf-8".
+        oWriter               = NEW WebResponseWriter(oResponse).
+                        
+        IF NOT lRetVal THEN 
+        DO:
+            oJsonMessage = NEW JsonObject().
+            oJsonMessage:ADD('success', FALSE).
+            oJsonMessage:ADD('message', 'Fehler beim Update/PATCH des Users').
+            oJsonMessage:WRITE(lcJsonString, FALSE).
+        END.
+        // MESSAGE 'R�ckmeldung ' STRING(lcJsonString).
+                            
+        oWriter:Open().
+        oWriter:Write(lcJsonString).
+        oWriter:Close().
+    
+        RETURN 0.
+    
+        CATCH e AS Progress.Lang.Error:
+                
+        END CATCH.
+                
+        FINALLY:
+        /*            DELETE OBJECT oJsonConfig. */
+        /*            DELETE OBJECT oJsonMessage.*/
+        END FINALLY.
+
+    END METHOD.
+    
+    
+    METHOD OVERRIDE PROTECTED INTEGER HandleNotAllowedMethod(INPUT poRequest AS IWebRequest):
+        DEFINE VARIABLE result AS INTEGER NO-UNDO.
+        MESSAGE "HandleNotAllowedMethod called" VIEW-AS ALERT-BOX.
+        RETURN result.
+    END METHOD.
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleNotImplemented(INPUT poRequest AS IWebRequest):
+        DEFINE VARIABLE result AS INTEGER NO-UNDO.
+        MESSAGE "HandleNotImplemented called" VIEW-AS ALERT-BOX.
+        RETURN result.
+    END METHOD.
+
+    DESTRUCTOR PUBLIC dynamicformImpl ( ):
+
+    END DESTRUCTOR.
+
+END CLASS.

+ 856 - 0
admin/formdesignerImpl.cls

@@ -0,0 +1,856 @@
+ 
+/*------------------------------------------------------------------------
+   File        : adresse_dict
+   Purpose     : 
+   Syntax      : 
+   Description : 
+   Author(s)   : walter.riechsteiner
+   Created     : Thu Jun 26 13:56:20 CEST 2025
+   Notes       : 
+ ----------------------------------------------------------------------*/
+ 
+BLOCK-LEVEL ON ERROR UNDO, THROW.
+
+USING OpenEdge.Core.String FROM PROPATH.
+USING OpenEdge.Net.HTTP.IHttpResponse FROM PROPATH.
+USING OpenEdge.Net.HTTP.StatusCodeEnum FROM PROPATH.
+USING OpenEdge.Web.IWebRequest FROM PROPATH.
+USING OpenEdge.Web.WebHandler FROM PROPATH.
+USING OpenEdge.Web.WebResponseWriter FROM PROPATH.
+USING Progress.Json.ObjectModel.JsonObject FROM PROPATH.
+USING Progress.Json.ObjectModel.JsonArray FROM PROPATH.
+USING Progress.Json.ObjectModel.ObjectModelParser FROM PROPATH.
+USING src.ch.adprime.gemis.WebHandlerUtilities FROM PROPATH.
+USING utilities.utilitiesHandler FROM PROPATH.
+USING Progress.Json.ObjectModel.JsonDataType FROM PROPATH.
+
+CLASS admin.formdesignerImpl INHERITS WebHandler: 
+
+    DEFINE VARIABLE oResponse         AS IHttpResponse     NO-UNDO.         
+    DEFINE VARIABLE oWriter           AS WebResponseWriter NO-UNDO.
+    DEFINE VARIABLE oBody             AS String            NO-UNDO.
+    
+    DEFINE VARIABLE ccompany          AS CHARACTER         NO-UNDO.
+    DEFINE VARIABLE cuser_name        AS CHARACTER         NO-UNDO.
+    DEFINE VARIABLE cAnzeigeName      AS CHARACTER         NO-UNDO.
+    DEFINE VARIABLE ilanguage_id      AS INTEGER           NO-UNDO.
+    DEFINE VARIABLE cSessionToken     AS CHARACTER         NO-UNDO.
+    
+    DEFINE VARIABLE outilitiesHandler AS utilitiesHandler  NO-UNDO.
+    
+    DEFINE TEMP-TABLE tcompanies
+        SERIALIZE-NAME 'companies'
+        FIELD company      AS CHARACTER SERIALIZE-NAME 'company'
+        FIELD company_Name AS CHARACTER SERIALIZE-NAME 'company_name'
+        FIELD lselected    AS LOGICAL   SERIALIZE-NAME 'selected'
+        .
+    DEFINE VARIABLE htcompanies AS HANDLE NO-UNDO.
+        
+    DEFINE TEMP-TABLE tusers
+        FIELD user_name    AS CHARACTER 
+        FIELD display_name AS CHARACTER
+        .
+    DEFINE VARIABLE htusers AS HANDLE NO-UNDO.
+    
+    DEFINE TEMP-TABLE tlanguages
+        FIELD language_id   AS INTEGER 
+        FIELD language_name AS CHAR
+        .
+    DEFINE VARIABLE htlanguages AS HANDLE NO-UNDO.
+        
+    DEFINE TEMP-TABLE tFileDict
+        SERIALIZE-NAME 'fields'
+        FIELD cId          AS CHARACTER SERIALIZE-NAME 'id'
+        FIELD cName        AS CHARACTER SERIALIZE-NAME 'fieldName'
+        FIELD cLabel       AS CHARACTER SERIALIZE-NAME 'label' 
+        FIELD cType        AS CHARACTER SERIALIZE-NAME 'type'
+        FIELD cDisplayType AS CHARACTER SERIALIZE-NAME 'displayType'
+        FIELD cInputMode   AS CHARACTER SERIALIZE-NAME 'inputMode'
+        FIELD lshowSpinner AS LOGICAL   SERIALIZE-NAME 'showSpinner'
+        FIELD cFormat      AS CHARACTER SERIALIZE-NAME 'format'
+        FIELD iMaxLength   AS INTEGER   SERIALIZE-NAME 'maxLength'
+        FIELD iDecimals    AS INTEGER   SERIALIZE-NAME 'decimalPlaces'
+        FIELD leditable    AS LOGICAL   SERIALIZE-NAME 'editable'
+        FIELD lhidden      AS LOGICAL   SERIALIZE-NAME 'hidden'
+        FIELD cAusrichtung AS CHARACTER SERIALIZE-NAME 'align'
+        .
+        
+    DEFINE TEMP-TABLE tConfig
+        SERIALIZE-NAME 'existingConfigs'
+        FIELD cId        AS CHARACTER SERIALIZE-NAME 'id'
+        FIELD cFormTitle AS CHARACTER SERIALIZE-NAME 'formTitle'
+        FIELD cFormId    AS CHARACTER SERIALIZE-NAME 'formId' 
+        FIELD cCreated   AS CHARACTER SERIALIZE-NAME 'created'
+        . 
+
+    DEFINE DATASET dsResponse
+        SERIALIZE-NAME 'dsResponse'
+        FOR tFileDict, tConfig.
+    DEFINE VARIABLE hdsResponse AS HANDLE NO-UNDO.
+        
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD PUBLIC LOGICAL createTemptable(
+        INPUT ipoJsonFields AS JsonArray,
+        OUTPUT ophtTable    AS HANDLE   ,
+        OUTPUT ophBuffer    AS HANDLE 
+        ):
+        
+        DEFINE VARIABLE lRetVal     AS LOGICAL    NO-UNDO.
+        DEFINE VARIABLE iType       AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE cType       AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cField      AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cFunction   AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE ii          AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE i1          AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE cFieldNames AS CHARACTER  NO-UNDO EXTENT.
+        DEFINE VARIABLE oJsonField  AS JsonObject NO-UNDO.
+
+        CREATE TEMP-TABLE ophtTable.
+        DO i1 = 1 TO ipoJsonFields:LENGTH:
+            oJsonField  = NEW JsonObject().
+            oJsonField  = ipoJsonFields:GetJsonObject(i1).
+            IF i1 = 1 THEN 
+            DO:
+                cFieldNames = oJsonField:getNames() NO-ERROR.
+                DO ii = 1 TO EXTENT(cFieldNames):
+                    cField = cFieldNames[ii].
+                    iType  = oJsonField:GetType(cField).
+                    cType  = ''.
+                    CASE iType:
+                        WHEN JsonDataType:STRING THEN 
+                            cType = 'character'.
+                        WHEN JsonDataType:NUMBER THEN 
+                            cType = 'integer'.
+                        WHEN JsonDataType:BOOLEAN THEN 
+                            cType = 'logical'.
+                        WHEN JsonDataType:OBJECT THEN 
+                            MESSAGE 'Json-Feldtype  OBJECT' cField.
+                        WHEN JsonDataType:ARRAY THEN 
+                            MESSAGE 'Json-Feldtype  ARRAY' cField.
+                        WHEN JsonDataType:NULL THEN 
+                            cType = 'character'.
+                    END CASE.
+                    IF cType = '' THEN cType = 'character'.
+                    ophtTable:ADD-NEW-FIELD(cField, cType) NO-ERROR.
+                END.
+                ophtTable:TEMP-TABLE-PREPARE('ttTemp').
+                ophBuffer = ophtTable:DEFAULT-BUFFER-HANDLE.
+            END.
+            ophBuffer:BUFFER-CREATE().
+            
+            DO ii = 1 TO EXTENT(cFieldNames):
+                cField = cFieldNames[ii].
+                CASE ophBuffer:BUFFER-FIELD(cField):DATA-TYPE:
+                    WHEN 'character' THEN 
+                        ophBuffer:BUFFER-FIELD(cField):BUFFER-VALUE = oJsonField:GetCharacter(cField) NO-ERROR. 
+                    WHEN 'integer' THEN 
+                        ophBuffer:BUFFER-FIELD(cField):BUFFER-VALUE = oJsonField:GetInteger(cField) NO-ERROR. 
+                    WHEN 'logical' THEN 
+                        ophBuffer:BUFFER-FIELD(cField):BUFFER-VALUE = STRING(oJsonField:GetLogical(cField)) NO-ERROR.
+                END CASE.
+                IF ophBuffer:BUFFER-FIELD(cField):BUFFER-VALUE = ? THEN ophBuffer:BUFFER-FIELD(cField):BUFFER-VALUE = ''.
+            END.
+            DELETE OBJECT oJsonField NO-ERROR.
+        END.
+
+        lRetVal = TRUE.
+        RETURN lRetVal.
+
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD PUBLIC LOGICAL fillFileDict(
+        INPUT oJsonIdent AS JsonObject
+        ):
+        
+        DEFINE VARIABLE lresult     AS LOGICAL   NO-UNDO INIT FALSE.
+        DEFINE VARIABLE ii          AS INTEGER   NO-UNDO.
+        DEFINE VARIABLE i1          AS INTEGER   NO-UNDO.
+        DEFINE VARIABLE i2          AS INTEGER   NO-UNDO.
+        DEFINE VARIABLE lRetVal     AS LOG       NO-UNDO INIT FALSE.
+        DEFINE VARIABLE hBuffer     AS HANDLE    NO-UNDO.
+        DEFINE VARIABLE hQuery      AS HANDLE    NO-UNDO.
+        DEFINE VARIABLE rFile       AS RECID     NO-UNDO.
+        DEFINE VARIABLE cViewas     AS CHARACTER NO-UNDO.
+        
+        DEFINE VARIABLE cFileNames  AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE cFileName   AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE cLDBName    AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE cDBName     AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE cTestName   AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE cDBFileName AS CHARACTER NO-UNDO.
+        EMPTY TEMP-TABLE tFileDict.
+
+        lRetVal = FALSE.
+        cFileNames = oJsonIdent:GetCharacter('tables').
+        DO ii = 1 TO NUM-ENTRIES(cFileNames, ';'):
+            cFileName = ENTRY(ii,cFileNames, ';').
+            
+            DO i1 = 1 TO NUM-DBS:
+                cDBName   = LDBNAME(i1).
+                cFileName = SUBSTITUTE('&1.&2', cDBName, cFileName) NO-ERROR.        
+                CREATE BUFFER hBuffer FOR TABLE cFileName NO-ERROR.
+                IF  ERROR-STATUS:ERROR        OR 
+                    NOT VALID-HANDLE(hBuffer) THEN NEXT.
+                /*                    lRetVal = hBuffer:FIND-FIRST('WHERE _File-Name = ' + QUOTER(cFileName), NO-LOCK) NO-ERROR.*/
+                /*                    IF lRetVal THEN                                                                           */
+                /*                    DO:                                                                                       */
+                /*                        rFile = hBuffer:RECID.                                                                */
+                /*                        DELETE OBJECT hBuffer NO-ERROR.                                                       */
+                /*                        LEAVE.                                                                                */
+                /*                    END.                                                                                      */
+                /*                    DELETE OBJECT hBuffer.                                                                    */
+                lRetVal = TRUE.
+            END.
+            IF NOT lRetVal THEN NEXT.
+            
+/*            cDBFileName = cDBName + '.' + '_Field'.                                                                                    */
+/*                                                                                                                                       */
+/*            CREATE BUFFER hBuffer FOR TABLE cDBFileName.                                                                               */
+/*            CREATE QUERY hQuery.                                                                                                       */
+/*            hQuery:SET-BUFFERS(hBuffer).                                                                                               */
+/*            hQuery:QUERY-PREPARE(SUBSTITUTE('FOR EACH &1 WHERE _Field._File-Recid = &2 NO-LOCK BY _Field._Order', cDBFileName, rFile)).*/
+/*            hQuery:QUERY-OPEN().                                                                                                       */
+ 
+            DO WHILE NOT hQuery:QUERY-OFF-END:
+                hQuery:GET-NEXT(NO-LOCK) NO-ERROR.
+                IF hQuery:QUERY-OFF-END THEN LEAVE.
+            DO i1 = 1 TO hBuffer:NUM-FIELDS:
+                IF hBuffer:BUFFER-FIELD(i1):NAME  = 'wordindex' THEN NEXT.
+
+                CREATE  tFileDict.
+                ASSIGN
+                    tFileDict.cId          = cFilename + '_' + hBuffer::_Field-Name
+                    tFileDict.cName        = cFilename + '_' + hBuffer::_Field-Name
+                    tFileDict.cFormat      = hBuffer::_Format
+                    tFileDict.cType        = hBuffer::_Data-Type
+                    tFileDict.iDecimals    = 0
+                    tFileDict.lhidden      = FALSE
+                    tFileDict.leditable    = TRUE
+                    tFileDict.iMaxLength   = 12
+                    tFileDict.cAusrichtung = 'left'
+                    tFileDict.cDisplayType = ?
+                    tFileDict.lShowSpinner = ?
+                    tFileDict.cInputMode   = ?
+                    .
+
+                FIND FIRST labeltexte NO-LOCK 
+                    WHERE labeltexte.company     = oJsonIdent:GetCharacter('company')
+                    AND   labeltexte.table_name  = cFileName
+                    AND   labeltexte.field_name  = hBuffer::_Field-Name
+                    AND   labeltexte.language_id = oJsonIdent:GetInteger('language_id') NO-ERROR.
+                IF NOT AVAILABLE labeltexte THEN 
+                DO:
+                    FIND FIRST labeltexte NO-LOCK 
+                        WHERE labeltexte.company     = oJsonIdent:GetCharacter('company')
+                        AND   labeltexte.table_name  = 'table'
+                        AND   labeltexte.field_name  = hBuffer::_Field-Name NO-ERROR.
+                END.
+                IF NOT AVAILABLE labeltexte THEN 
+                DO:
+                    FIND FIRST labeltexte NO-LOCK 
+                        WHERE labeltexte.company     = oJsonIdent:GetCharacter('company')
+                        AND   labeltexte.field_name  = hBuffer::_Field-Name
+                        AND   labeltexte.language_id = oJsonIdent:GetInteger('language_id') NO-ERROR.
+                END.
+
+                IF AVAILABLE labeltexte THEN 
+                DO:
+                    tFileDict.cLabel = labeltexte.sidelabel.
+                END.
+                ELSE 
+                DO:
+                    tFileDict.cLabel = (IF hBuffer::_Label <> ? THEN hBuffer::_Label ELSE hBuffer::_Field-Name). 
+                END.
+
+                IF INDEX(hBuffer::_Format, '(') = 0 THEN tFileDict.iMaxLength = LENGTH(hBuffer::_Format).
+                ELSE 
+                DO:
+                    i1 = INDEX(hBuffer::_Format, '(') + 1.
+                    i2 = INDEX(hBuffer::_Format, ')').
+                    tFileDict.iMaxLength = INTEGER(SUBSTRING(hBuffer::_Format, i1, i2 - i1)).
+                END.
+                
+                CASE tFileDict.cType:
+                    WHEN 'character' THEN 
+                        DO: 
+                            ASSIGN 
+                                tFileDict.cType     = 'text'
+                                tFileDict.iDecimals = 0.
+                            IF hBuffer::_Extent > 0 THEN tFileDict.cType = 'textarea'. 
+                        END.
+                    WHEN 'Date' THEN 
+                        DO: 
+                            ASSIGN 
+                                tFileDict.cType        = 'date'
+                                tFileDict.cFormat      = '99.99.9999'
+                                tFileDict.iDecimals    = 0
+                                tFileDict.iMaxLength   = tFileDict.iMaxLength + 2
+                                tFileDict.cAusrichtung = 'center'.
+                        END.
+                    WHEN 'Decimal' THEN 
+                        DO: 
+                            ASSIGN 
+                                tFileDict.cType        = 'decimal'
+                                tFileDict.iDecimals    = hBuffer::_Decimals
+                                tFileDict.cDisplayType = 'text'
+                                tFileDict.cInputMode   = 'decimal'
+                                tFileDict.lShowSpinner = FALSE
+                                tFileDict.iMaxLength   = tFileDict.iMaxLength
+                                tFileDict.cAusrichtung = 'right'.
+                        END.
+                    WHEN 'Integer' OR
+                    WHEN 'Int64'   THEN 
+                        DO: 
+                            ASSIGN 
+                                tFileDict.cType        = 'integer'
+                                tFileDict.iDecimals    = 0
+                                tFileDict.cDisplayType = 'text'
+                                tFileDict.cInputMode   = 'numeric'
+                                tFileDict.lShowSpinner = FALSE
+                                tFileDict.iMaxLength   = tFileDict.iMaxLength
+                                tFileDict.cAusrichtung = 'right'.
+                        END.
+                    WHEN 'Recid' THEN 
+                        DO: 
+                            ASSIGN 
+                                tFileDict.cType        = 'integer'
+                                tFileDict.iDecimals    = 0
+                                tFileDict.cDisplayType = 'text'
+                                tFileDict.cInputMode   = 'text'
+                                tFileDict.lShowSpinner = FALSE
+                                tFileDict.lHidden      = TRUE
+                                tFileDict.leditable    = FALSE.
+                        END.
+                    WHEN 'logical' THEN 
+                        DO:
+                            ASSIGN  
+                                tFileDict.cType        = 'checkbox'
+                                tFileDict.cAusrichtung = 'center'.
+                        END.
+                END CASE.
+                
+                cViewas = hBuffer::_View-as.
+                CASE cViewas:
+                    WHEN 'combo-box' THEN 
+                        tFileDict.cType = 'select'.
+                    WHEN 'editor' THEN
+                        ASSIGN  
+                            tFileDict.cType = 'textarea'.
+                END CASE.
+                 
+            /*                tFileDict.cFormat = REPLACE(tFileDict.cFormat, '9', '0').*/
+            /*                tFileDict.cFormat = REPLACE(tFileDict.cFormat, '>', ''). */
+            /*                tFileDict.cFormat = REPLACE(tFileDict.cFormat, '<', ''). */
+            /*                tFileDict.cAusrichtung = 'right'.                        */
+            END.
+            hQuery:QUERY-CLOSE().
+            DELETE OBJECT hBuffer.
+            DELETE OBJECT hQuery.
+        END.
+        
+        lResult = TRUE.
+
+        RETURN lresult.
+
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleGet (INPUT poRequest AS IWebRequest ):
+        DEFINE VARIABLE oJsonResponse   AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonIdent      AS JsonObject        NO-UNDO.
+        
+        DEFINE VARIABLE oJsonCompanies  AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE oJsonUsers      AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE oJsonLanguages  AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE oBody           AS String            NO-UNDO.
+        
+        DEFINE VARIABLE oJsonFileDict   AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonConfig     AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonArray      AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE cDefautlCharSet AS CHARACTER         NO-UNDO INIT 'UTF-8'.
+        DEFINE VARIABLE oParser         AS ObjectModelParser NO-UNDO.           
+        DEFINE VARIABLE cCorralationID  AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cContent-Type   AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE htFileDict      AS HANDLE            NO-UNDO.
+        DEFINE VARIABLE htConfig        AS HANDLE            NO-UNDO.
+        DEFINE VARIABLE lcJsonInhalt    AS LONGCHAR          NO-UNDO.
+        DEFINE VARIABLE cFileNames      AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cFileName       AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE ii              AS INTEGER           NO-UNDO.
+        DEFINE VARIABLE dDateTime       AS DATETIME          NO-UNDO.
+        DEFINE VARIABLE cDateTime       AS CHARACTER         NO-UNDO.
+        
+        DEFINE VARIABLE oJsonMenu       AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE oJsonData       AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE cConfig_id      AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE lRetVal         AS LOGICAL           NO-UNDO INIT FALSE.
+        DEFINE VARIABLE cFunction       AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cQueryString    AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cQueryPairs     AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cQueryKey       AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cQueryValue     AS CHARACTER         NO-UNDO.
+        
+        outilitiesHandler = NEW utilitiesHandler().
+
+        outilitiesHandler:getHeaderData(
+            INPUT  poRequest    ,
+            OUTPUT ccompany     ,
+            OUTPUT cuser_name   ,
+            OUTPUT cAnzeigeName ,
+            OUTPUT ilanguage_id ,
+            OUTPUT cSessionToken
+            ).
+        
+        oJsonIdent = NEW JsonObject().
+        oJsonIdent:ADD('H_company'     , ccompany     )   NO-ERROR.
+        oJsonIdent:ADD('H_user_name'   , cuser_name   )   NO-ERROR.
+        oJsonIdent:ADD('H_display_name', cAnzeigeName )   NO-ERROR.
+        oJsonIdent:ADD('H_language_id' , iLanguage_id )   NO-ERROR.
+        oJsonIdent:ADD('H_sessionToken', cSessionToken)   NO-ERROR.
+        //
+        //  Alle Parameter aus dem Query-String lesen und im Object oJsonIdent ergänzenz
+        //
+        cQueryString = STRING(poRequest:GetContextValue("QUERY_STRING"))    NO-ERROR.
+        DO ii = 1 TO NUM-ENTRIES(cQueryString, '&'):
+            cQueryPairs = ENTRY(ii, cQueryString, '&').
+            cQueryKey   = ENTRY(1 , cQueryPairs , '=').
+            cQueryValue = ENTRY(2 , cQueryPairs , '=').
+            IF oJsonIdent:Has(cQueryKey) THEN oJsonIdent:SET(cQueryKey, cQueryValue) NO-ERROR.
+            ELSE                              oJsonIdent:ADD(cQueryKey, cQueryValue) NO-ERROR.
+        END.
+        
+        IF NOT oJsonIdent:HAS('company'    ) THEN oJsonIdent:ADD('company'    , oJsonIdent:GetCharacter('H_company'    )).
+        IF NOT oJsonIdent:HAS('user_name'  ) THEN oJsonIdent:ADD('user_name'  , oJsonIdent:GetCharacter('H_user_name'  )).
+        IF NOT oJsonIdent:HAS('language_id') THEN oJsonIdent:ADD('language_id', oJsonIdent:GetInteger  ('H_language_id')).
+        
+        oJsonIdent:WriteFile('C:\TEMP\formdesigner_GET.json', TRUE).
+        
+        cFileNames = REPLACE(oJsonIdent:GetCharacter("tables"), ',', ';')  NO-ERROR.
+        cFunction  = oJsonIdent:GetCharacter('function').
+
+        DO WHILE cFunction = 'init':
+            
+            EMPTY TEMP-TABLE tcompanies.
+            FOR EACH companies NO-LOCK WHERE companies.active:
+                CREATE  tcompanies.
+                BUFFER-COPY companies TO tcompanies.
+                ASSIGN 
+                    tcompanies.lselected = (IF companies.company = ccompany THEN TRUE ELSE FALSE).
+            END.
+            
+            EMPTY TEMP-TABLE tusers.
+            FOR EACH users NO-LOCK WHERE users.active:
+                CREATE  tusers.
+                BUFFER-COPY users TO tusers.
+            END.
+            
+            EMPTY TEMP-TABLE tlanguages.
+            FOR EACH languages NO-LOCK:
+                CREATE  tlanguages.
+                BUFFER-COPY languages TO tlanguages.
+            END.
+            
+            oJsonResponse   = NEW JsonObject().
+            oJsonCompanies  = NEW JsonArray().
+            oJsonUsers      = NEW JsonArray().
+            oJsonLanguages  = NEW JsonArray().
+            
+            htcompanies = TEMP-TABLE tcompanies:DEFAULT-BUFFER-HANDLE.
+            htusers     = TEMP-TABLE tusers    :DEFAULT-BUFFER-HANDLE.
+            htlanguages = TEMP-TABLE tlanguages:DEFAULT-BUFFER-HANDLE.
+            
+            htcompanies:WRITE-JSON('JsonArray', oJsonCompanies ).
+            htusers    :WRITE-JSON('JsonArray', oJsonUsers     ).
+            htlanguages:WRITE-JSON('JsonArray', oJsonLanguages ).
+            
+            oJsonResponse:ADD('companies', oJsonCompanies).
+            oJsonResponse:ADD('users'    , oJsonUsers    ).
+            oJsonResponse:ADD('languages', oJsonLanguages).
+            
+            oJsonResponse:WRITE(lcJsonInhalt, FALSE).
+            
+            lRetVal = TRUE.
+            LEAVE.
+        END.
+        
+        DO WHILE cFunction = 'load': 
+            fillFileDict(
+                INPUT oJsonIdent
+                ).
+
+            EMPTY TEMP-TABLE tConfig.
+            FOR EACH htmldokumente NO-LOCK 
+                WHERE htmldokumente.company     = ccompany
+                AND   htmldokumente.user_name   = cuser_name
+                AND   htmldokumente.language_id = ilanguage_id:
+                    
+                DO ii = 1 TO NUM-ENTRIES(cFileNames, ';'):
+                    cFileName = ENTRY(ii, cFileNames, ';').
+
+                    IF INDEX(htmldokumente.Form_Id, cFileName) = 0 THEN NEXT.
+                    
+                    IF htmldokumente.updated_at = ? THEN 
+                    DO:
+                        dDateTime = htmldokumente.created_at. 
+                        cDateTime = STRING(htmldokumente.created_at,'99-99-9999THH:MM:SS').
+                    END.
+                    ELSE 
+                    DO:
+                        dDateTime = htmldokumente.updated_at. 
+                        cDateTime = STRING(htmldokumente.updated_at,'99-99-9999THH:MM:SS').
+                    END.
+
+                    CREATE  tConfig.
+                    ASSIGN  
+                        tConfig.cId        = htmldokumente.form_id
+                        tConfig.cFormTitle = htmldokumente.formtitle
+                        tConfig.cCreated   = STRING(YEAR(dDateTime),'9999')
+                                       + '-'
+                                       + STRING(MONTH(dDateTime),'99')
+                                       + '-'
+                                       + STRING(DAY(dDateTime),'99')
+                                       + SUBSTRING(cDateTime,11).
+
+                    LEAVE.
+                END.
+            END.
+        
+            htFileDict  = TEMP-TABLE tFileDict :DEFAULT-BUFFER-HANDLE.
+            htConfig    = TEMP-TABLE tConfig   :DEFAULT-BUFFER-HANDLE.
+            hdsResponse = DATASET    dsResponse:HANDLE.
+                 
+            oJsonResponse = NEW JsonObject().
+            oJsonResponse:READ(hdsResponse).
+            oJsonResponse:WRITE(lcJsonInhalt, FALSE).
+        
+            lRetVal = TRUE.
+            LEAVE.
+        END.
+        
+        DO WHILE cFunction = 'delete':
+            lRetVal = FALSE.
+            REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
+                FIND FIRST htmldokumente 
+                    WHERE htmldokumente.company     = ccompany
+                    AND   htmldokumente.user_name   = cuser_name
+                    AND   htmldokumente.language_id = ilanguage_id
+                    AND   htmldokumente.form_id     = cConfig_id NO-ERROR.
+                IF NOT AVAILABLE htmldokumente THEN LEAVE.
+                DELETE  htmldokumente.
+                lRetVal = TRUE.
+                LEAVE.
+            END.
+            
+            oJsonResponse   = NEW JsonObject().
+            oJsonResponse:ADD("success", lRetVal).
+            IF lRetVal THEN oJsonResponse:ADD('message', 'Konfiguration erfolreich gel�scht').
+            ELSE            oJsonResponse:ADD('error'  , 'Konfiguration nicht gefunden'     ).
+            oJsonResponse:write(lcJsonInhalt, FALSE).
+                            
+            LEAVE.
+        END.
+        
+        DO WHILE cFunction = 'loaddetail':
+            FIND FIRST htmldokumente NO-LOCK 
+                WHERE htmldokumente.company     = ccompany
+                AND   htmldokumente.user_name   = cuser_name
+                AND   htmldokumente.language_id = ilanguage_id
+                AND   htmldokumente.form_id     = cConfig_id NO-ERROR.
+                
+            lcJsonInhalt    = htmldokumente.htmltext.
+            lRetVal         = TRUE.
+            LEAVE.
+        END.
+        
+        IF NOT lRetVal THEN 
+        DO:
+            oJsonResponse = NEW JsonObject().
+            oJsonResponse:ADD('success', FALSE).
+            oJsonResponse:WRITE(lcJsonInhalt, FALSE).
+        END.
+                
+        cContent-Type   = "application/json".
+        cDefautlCharSet = 'utf-8'.
+        oBody           = NEW STRING(lcJsonInhalt).
+        WebHandlerUtilities:createHttpResponse(INPUT INTEGER(StatusCodeEnum:OK), INPUT oBody, INPUT cContent-Type, INPUT cDefautlCharSet, INPUT cCorralationID, OUTPUT oResponse).
+           
+        oWriter = NEW WebResponseWriter(oResponse).
+        oWriter:Open(). 
+        oWriter:Close(). 
+
+        RETURN 0.
+        
+        CATCH e AS Progress.Lang.Error:
+
+        END CATCH.
+
+        FINALLY:
+
+        END FINALLY.
+
+    END METHOD.
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleNotAllowedMethod(INPUT poRequest AS IWebRequest):
+        DEFINE VARIABLE result AS INTEGER NO-UNDO.
+        MESSAGE "HandleNotAllowedMethod called" VIEW-AS ALERT-BOX.
+        RETURN result.
+    END METHOD.
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleNotImplemented(INPUT poRequest AS IWebRequest):
+        DEFINE VARIABLE result AS INTEGER NO-UNDO.
+        MESSAGE "HandleNotImplemented called" VIEW-AS ALERT-BOX.
+        RETURN result.
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD OVERRIDE PROTECTED INTEGER HandlePost(INPUT poRequest AS IWebRequest):
+        
+        DEFINE VARIABLE oResponse    AS IHttpResponse     NO-UNDO.
+        DEFINE VARIABLE oWriter      AS WebResponseWriter NO-UNDO.
+        DEFINE VARIABLE oJsonData    AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonMessage AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oFelder      AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE oFeld        AS JsonObject        NO-UNDO.
+        
+        DEFINE VARIABLE lRetVal      AS LOGICAL           NO-UNDO.
+        DEFINE VARIABLE lcJsonString AS LONGCHAR          NO-UNDO.
+        DEFINE VARIABLE cJSON        AS LONGCHAR          NO-UNDO.
+        DEFINE VARIABLE i1           AS INTEGER           NO-UNDO.
+        DEFINE VARIABLE ii           AS INTEGER           NO-UNDO.
+        DEFINE VARIABLE oJsonConfig  AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonFields  AS JsonArray         NO-UNDO.
+        
+        DEFINE VARIABLE ctables      AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE ccompany     AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cuser_name   AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE ilanguage_id AS INTEGER           NO-UNDO.
+        DEFINE VARIABLE cformtitle   AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cformid      AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE lcJsonConfig AS LONGCHAR          NO-UNDO.
+        
+        DEFINE VARIABLE htTable      AS HANDLE            NO-UNDO.
+        DEFINE VARIABLE hBuffer      AS HANDLE            NO-UNDO.
+        DEFINE VARIABLE hQuery       AS HANDLE            NO-UNDO.
+        DEFINE VARIABLE cFunction    AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cFieldNames  AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cFieldName   AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cFileName    AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cBoxfields   AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE lBoxField    AS LOGICAL           NO-UNDO.
+        
+        lRetVal = WebHandlerUtilities:getJsonFromRequest(INPUT poRequest, OUTPUT oJsonData) NO-ERROR.
+        // MESSAGE 'getJsonFromRequest    = ' lRetVal.
+        
+        cFunction = poRequest:URI:GetQueryValue("function").
+        // MESSAGE 'Funktion = ' cFunction.
+        
+        oJsonData:WRITE(lcJsonString, FALSE).
+        MESSAGE 'ganzer Eingangsstring = ' STRING(lcJsonString).
+        
+        ccompany     =         oJsonData:GetCharacter('company' ).
+        cuser_name   =         oJsonData:GetCharacter('user_name' ).
+        ilanguage_id = INTEGER(oJsonData:GetCharacter('language_id')).
+        ctables      =         oJsonData:GetCharacter('tables').
+        // MESSAGE ccompany '-' cuser_name '-' ilanguage_id '-' ctables.
+        
+        oJsonConfig = NEW JsonObject().
+        oJsonConfig = oJsonData:GetJsonObject ('config').
+        cformtitle  = oJsonConfig:GetCharacter('formTitle').
+        cformid     = oJsonConfig:GetCharacter('formId').
+        oJsonFields = NEW JsonArray().
+        oJsonFields = oJsonConfig:GetJsonArray('selectedFields').
+        oJsonConfig:WRITE(lcJsonConfig, FALSE).
+        
+        oJsonConfig:WriteFile('C:\TEMP\FormDesignerOutput.json', TRUE).
+        
+        createTemptable (
+            INPUT  oJsonFields,
+            OUTPUT htTable    ,
+            OUTPUT hBuffer    ).
+        
+        hBuffer:WRITE-JSON ('file', 'C:\TEMP\FeldAttributeAusFormdesigner.csv', TRUE).
+
+        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
+            FIND htmldokumente
+                WHERE htmldokumente.company     = ccompany
+                AND   htmldokumente.user_name   = cuser_name
+                AND   htmldokumente.form_id     = cformid
+                AND   htmldokumente.language_id = ilanguage_id NO-ERROR.
+            IF NOT AVAILABLE htmldokumente THEN 
+            DO:
+                CREATE  htmldokumente.
+                ASSIGN 
+                    htmldokumente.company     = ccompany
+                    htmldokumente.user_name   = cuser_name
+                    htmldokumente.form_id     = cformid
+                    htmldokumente.language_id = ilanguage_id
+                    htmldokumente.created_at  = NOW.
+            END.
+            ASSIGN 
+                htmldokumente.tables    = ctables
+                htmldokumente.formtitle = cformtitle.
+            htmltext = STRING(lcJsonConfig).
+            // MESSAGE 'htmldokument gschrieben mit config ' STRING(lcJsonConfig).
+            RELEASE htmldokumente.
+            LEAVE.
+        END.
+        
+        cBoxfields = ''.
+        CREATE QUERY hQuery.
+        hQuery:SET-BUFFERS(hBuffer).
+        hQuery:QUERY-PREPARE ('FOR EACH ttTemp NO-LOCK').
+        hQuery:QUERY-OPEN ().
+        hQUery:GET-FIRST ().
+        DO WHILE NOT hQuery:QUERY-OFF-END TRANSACTION:
+            cFieldName = hBuffer:BUFFER-FIELD('fieldName'):BUFFER-VALUE.
+            cFileName  = ENTRY(1, cFieldName, '_').
+            FIND FIRST labeltexte
+                WHERE labeltexte.company     = ccompany
+                AND   labeltexte.user_name   = cuser_name
+                AND   labeltexte.program     = cformid
+                AND   labeltexte.table_name  = cFileName
+                AND   labeltexte.field_name  = cFieldName
+                AND   labeltexte.language_id = ilanguage_id NO-ERROR.
+            IF NOT AVAILABLE labeltexte THEN 
+            DO:
+                CREATE  labeltexte.
+                ASSIGN
+                    labeltexte.company     = ccompany
+                    labeltexte.user_name   = cuser_name
+                    labeltexte.program     = cformid
+                    labeltexte.table_name  = cFileName
+                    labeltexte.field_name  = cFieldName
+                    labeltexte.language_id = ilanguage_id.
+            END.
+            ASSIGN 
+                labeltexte.sidelabel = hBuffer:BUFFER-FIELD('label'):BUFFER-VALUE
+                labeltexte.headlabel = hBuffer:BUFFER-FIELD('label'):BUFFER-VALUE
+                labeltexte.alignment = hBuffer:BUFFER-FIELD('align'):BUFFER-VALUE.
+                
+            FIND FIRST labeltexte
+                WHERE labeltexte.company     = ccompany
+                AND   labeltexte.user_name   = ''
+                AND   labeltexte.program     = ''
+                AND   labeltexte.table_name  = cFileName
+                AND   labeltexte.field_name  = cFieldName
+                AND   labeltexte.language_id = ilanguage_id NO-ERROR.
+            IF NOT AVAILABLE labeltexte THEN 
+            DO:
+                CREATE  labeltexte.
+                ASSIGN
+                    labeltexte.company     = ccompany
+                    labeltexte.user_name   = ''
+                    labeltexte.program     = ''
+                    labeltexte.table_name  = cFileName
+                    labeltexte.field_name  = cFieldName
+                    labeltexte.language_id = ilanguage_id
+                    labeltexte.sidelabel   = hBuffer:BUFFER-FIELD('label'):BUFFER-VALUE
+                    labeltexte.headlabel   = hBuffer:BUFFER-FIELD('label'):BUFFER-VALUE
+                    labeltexte.alignment   = hBuffer:BUFFER-FIELD('align'):BUFFER-VALUE.
+            END.
+            
+            FIND FIRST labeltexte
+                WHERE labeltexte.company     = ccompany
+                AND   labeltexte.user_name   = ''
+                AND   labeltexte.program     = ''
+                AND   labeltexte.table_name  = ''
+                AND   labeltexte.field_name  = cFieldName
+                AND   labeltexte.language_id = ilanguage_id NO-ERROR.
+            IF NOT AVAILABLE labeltexte THEN 
+            DO:
+                CREATE  labeltexte.
+                ASSIGN
+                    labeltexte.company     = ccompany
+                    labeltexte.user_name   = ''
+                    labeltexte.program     = ''
+                    labeltexte.table_name  = ''
+                    labeltexte.field_name  = cFieldName
+                    labeltexte.language_id = ilanguage_id
+                    labeltexte.sidelabel   = hBuffer:BUFFER-FIELD('label'):BUFFER-VALUE
+                    labeltexte.headlabel   = hBuffer:BUFFER-FIELD('label'):BUFFER-VALUE
+                    labeltexte.alignment   = hBuffer:BUFFER-FIELD('align'):BUFFER-VALUE.
+            END.
+            RELEASE labeltexte.
+            
+            lBoxField = (IF hBuffer:BUFFER-FIELD('type'):BUFFER-VALUE = 'select' THEN TRUE ELSE FALSE).
+            IF lBoxField THEN 
+            DO:
+                cBoxFields = cBoxfields
+                    + (IF cBoxfields = '' THEN '' ELSE ';')
+                    + hBuffer:BUFFER-FIELD('fieldName'):BUFFER-VALUE.
+            END.
+            
+            hQuery:GET-NEXT ().
+        END. 
+        
+        IF cBoxfields <> '' THEN 
+        DO:
+            REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
+                FIND FIRST selectboxfields
+                    WHERE selectboxfields.company   = ccompany
+                    AND   selectboxfields.program   = cFormId
+                    AND   selectboxfields.user_name = ''
+                    AND   selectboxfield.table_Name = '' NO-ERROR.
+                IF NOT AVAILABLE selectboxfields THEN 
+                DO:
+                    CREATE  selectboxfields.
+                    ASSIGN
+                        selectboxfields.company   = ccompany
+                        selectboxfields.program   = cFormId
+                        selectboxfields.user_name = ''
+                        selectboxfield.table_Name = ''.
+                END.
+                ASSIGN 
+                    selectboxfield.boxfields = cBoxFields.
+                RELEASE selectboxfields.
+                LEAVE.
+            END.
+        END. 
+        
+        // MESSAGE 'geschrieben ' ccompany '-' cuser_name '-' cformid '-' ilanguage_id.
+            
+        oResponse             = NEW OpenEdge.Web.WebResponse().
+        oResponse:StatusCode  = INTEGER(StatusCodeEnum:OK).
+        oResponse:ContentType = "application/json;charset=utf-8".
+        oWriter               = NEW WebResponseWriter(oResponse).
+        
+        oJsonMessage = NEW JsonObject().
+        oJsonMessage:ADD('id', cformid).
+        oJsonMessage:ADD('message', 'erfolgreich gespeichert').
+        oJsonMessage:WRITE(lcJsonString, TRUE).
+        // MESSAGE 'R�ckmeldung ' STRING(lcJsonString).
+            
+        oWriter:Open().
+        oWriter:Write(lcJsonString).
+        oWriter:Close().
+
+        CATCH e AS Progress.Lang.Error:
+
+        END CATCH.
+
+        FINALLY:
+        /*            DELETE OBJECT oJsonConfig  NO-ERROR.*/
+        /*            DELETE OBJECT oJsonMessage NO-ERROR.*/
+        /*            DELETE OBJECT oJsonFields  NO-ERROR.*/
+        END FINALLY.
+
+    END METHOD.
+
+END CLASS.

+ 388 - 0
admin/formprogramImpl.cls

@@ -0,0 +1,388 @@
+ 
+/*------------------------------------------------------------------------
+   File        : adresse_dict
+   Purpose     : 
+   Syntax      : 
+   Description : 
+   Author(s)   : walter.riechsteiner
+   Created     : Thu Jun 26 13:56:20 CEST 2025
+   Notes       : 
+ ----------------------------------------------------------------------*/
+ 
+BLOCK-LEVEL ON ERROR UNDO, THROW.
+
+USING OpenEdge.Core.String FROM PROPATH.
+USING OpenEdge.Net.HTTP.IHttpResponse FROM PROPATH.
+USING OpenEdge.Net.HTTP.StatusCodeEnum FROM PROPATH.
+USING OpenEdge.Web.IWebRequest FROM PROPATH.
+USING OpenEdge.Web.WebHandler FROM PROPATH.
+USING OpenEdge.Web.WebResponseWriter FROM PROPATH.
+USING Progress.Json.ObjectModel.* FROM PROPATH.
+USING src.ch.adprime.gemis.WebHandlerUtilities FROM PROPATH.
+USING utilities.utilitiesHandler FROM PROPATH.
+USING utilities.selectboxHandler FROM PROPATH.
+USING OpenEdge.Web.DataObject.Writer.JsonArrayValueWriter FROM PROPATH.
+
+CLASS admin.formprogramImpl INHERITS WebHandler: 
+
+    DEFINE VARIABLE ccompany          AS CHARACTER        NO-UNDO.
+    DEFINE VARIABLE cuser_name        AS CHARACTER        NO-UNDO.
+    DEFINE VARIABLE cAnzeigeName      AS CHARACTER        NO-UNDO.
+    DEFINE VARIABLE ilanguage_id      AS INTEGER          NO-UNDO.
+    DEFINE VARIABLE cSessionToken     AS CHARACTER        NO-UNDO.
+    
+    DEFINE VARIABLE outilitiesHandler AS utilitiesHandler NO-UNDO.
+    DEFINE VARIABLE oSelectboxHandler AS selectboxHandler NO-UNDO.
+    
+    DEFINE TEMP-TABLE tcompanies
+        SERIALIZE-NAME 'companies'
+        FIELD company      AS CHARACTER SERIALIZE-NAME 'company'
+        FIELD company_Name AS CHARACTER SERIALIZE-NAME 'company_name'
+        FIELD lselected    AS LOGICAL   SERIALIZE-NAME 'selected'
+        .
+    DEFINE VARIABLE htcompanies AS HANDLE NO-UNDO.
+        
+    DEFINE TEMP-TABLE tusers
+        FIELD user_name    AS CHARACTER 
+        FIELD display_name AS CHARACTER
+        .
+    DEFINE VARIABLE htusers AS HANDLE NO-UNDO.
+    
+    DEFINE TEMP-TABLE tlanguages
+        FIELD language_id   AS INTEGER 
+        FIELD language_name AS CHAR
+        .
+    DEFINE VARIABLE htlanguages AS HANDLE NO-UNDO.
+    
+    
+    DEFINE TEMP-TABLE tSellanguages
+        FIELD language_id   AS INTEGER   SERIALIZE-NAME 'language_id'
+        FIELD language_name AS CHARACTER 
+        .
+    /*    DEFINE DATASET DSselectOptions                            */
+    /*        SERIALIZE-NAME 'selectOptyions'                       */
+    /*        FOR tSelCompanies, tSelLanguages, tSelRole, tSelStore.*/
+    /*    DEFINE VARIABLE hDSselectOptions AS HANDLE.               */
+    
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleGet (INPUT poRequest AS IWebRequest ):
+        DEFINE VARIABLE oResponse           AS IHttpResponse     NO-UNDO.         
+        DEFINE VARIABLE oWriter             AS WebResponseWriter NO-UNDO.
+        DEFINE VARIABLE oBody               AS String            NO-UNDO.
+        DEFINE VARIABLE cDefautlCharSet     AS CHARACTER         NO-UNDO INIT 'UTF-8'.
+        DEFINE VARIABLE oParser             AS ObjectModelParser NO-UNDO.           
+        DEFINE VARIABLE cCorralationID      AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cContent-Type       AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE lcJsonInhalt        AS LONGCHAR          NO-UNDO.
+        DEFINE VARIABLE ii                  AS INTEGER           NO-UNDO.
+        DEFINE VARIABLE i1                  AS INTEGER           NO-UNDO.
+        
+        DEFINE VARIABLE oJsonResponse       AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonCompanies      AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE oJsonUsers          AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE oJsonLanguages      AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE oJsonBox            AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE oJsonSelectedFields AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE oJsonData           AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonIdent          AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonSelectBoxes    AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonRecords        AS JsonArray         NO-UNDO.
+        
+        DEFINE VARIABLE ccompany            AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cuser_name          AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE ilanguage_id        AS INTEGER           NO-UNDO.
+        DEFINE VARIABLE cFunction           AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cForm_Id            AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE lRetVal             AS LOGICAL           NO-UNDO.
+        DEFINE VARIABLE httBuffer           AS HANDLE            NO-UNDO.
+        DEFINE VARIABLE cFiles              AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cFile               AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cFileName           AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cFieldName          AS CHARACTER         NO-UNDO.
+        
+        DEFINE VARIABLE cQueryString        AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cQueryPairs         AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cQueryKey           AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cQueryValue         AS CHARACTER         NO-UNDO.
+        
+        DEFINE BUFFER bwebmenu FOR webmenu.
+        
+        outilitiesHandler = NEW utilitiesHandler().
+        oselectboxHandler = NEW selectboxHandler().
+        
+        cFunction = poRequest:URI:GetQueryValue("function") NO-ERROR.
+        
+        outilitiesHandler:getHeaderData(
+            INPUT  poRequest    ,
+            OUTPUT ccompany     ,
+            OUTPUT cuser_name   ,
+            OUTPUT cAnzeigeName ,
+            OUTPUT ilanguage_id ,
+            OUTPUT cSessionToken
+            ).
+
+        oJsonIdent = NEW JsonObject().
+        oJsonIdent:ADD('company'     , ccompany     ).
+        oJsonIdent:ADD('user_name'   , cuser_name   ).
+        oJsonIdent:ADD('language_id' , iLanguage_id ).
+        oJsonIdent:ADD('sessionToken', cSessionToken).
+        oJsonIdent:ADD('function'    , cFunction    ).
+        
+        cQueryString = STRING(poRequest:GetContextValue("QUERY_STRING"))    NO-ERROR.
+        DO ii = 1 TO NUM-ENTRIES(cQueryString, '&'):
+            cQueryPairs = ENTRY(ii, cQueryString, '&').
+            cQueryKey   = ENTRY(1 , cQueryPairs , '=').
+            cQueryValue = ENTRY(2 , cQueryPairs , '=').
+            IF oJsonIdent:Has(cQueryKey) THEN oJsonIdent:SET(cQueryKey, cQueryValue) NO-ERROR.
+            ELSE                              oJsonIdent:ADD(cQueryKey, cQueryValue) NO-ERROR.
+        END.
+        cFunction = oJsonIdent:GetCharacter('function').
+        
+        // MESSAGE 'Inhalt von Header und Query ' STRING(oJsonIdent:GetJsonText()).
+        
+        lRetVal = FALSE.
+        DO WHILE cFunction = 'init':
+            EMPTY TEMP-TABLE tcompanies.
+            FOR EACH companies NO-LOCK WHERE companies.active:
+                CREATE  tcompanies.
+                BUFFER-COPY companies TO tcompanies.
+                ASSIGN 
+                    tcompanies.lselected = (IF companies.company = ccompany THEN TRUE ELSE FALSE).
+            END.
+            
+            EMPTY TEMP-TABLE tusers.
+            FOR EACH users NO-LOCK WHERE users.active:
+                CREATE  tusers.
+                BUFFER-COPY users TO tusers.
+            END.
+            
+            EMPTY TEMP-TABLE tlanguages.
+            FOR EACH languages NO-LOCK:
+                CREATE  tlanguages.
+                BUFFER-COPY languages TO tlanguages.
+            END.
+            
+            oJsonResponse   = NEW JsonObject().
+            oJsonCompanies  = NEW JsonArray().
+            oJsonUsers      = NEW JsonArray().
+            oJsonLanguages  = NEW JsonArray().
+            
+            htcompanies = TEMP-TABLE tcompanies:DEFAULT-BUFFER-HANDLE.
+            htusers     = TEMP-TABLE tusers    :DEFAULT-BUFFER-HANDLE.
+            htlanguages = TEMP-TABLE tlanguages:DEFAULT-BUFFER-HANDLE.
+            
+            htcompanies:WRITE-JSON('JsonArray', oJsonCompanies ).
+            htusers    :WRITE-JSON('JsonArray', oJsonUsers     ).
+            htlanguages:WRITE-JSON('JsonArray', oJsonLanguages ).
+            
+            oJsonResponse:ADD('companies', oJsonCompanies).
+            oJsonResponse:ADD('users'    , oJsonUsers    ).
+            oJsonResponse:ADD('languages', oJsonLanguages).
+            
+            // oJsonResponse:WriteFile('C:\TEMP\init.json', TRUE).
+            oJsonResponse:WRITE(lcJsonInhalt, FALSE).
+            
+            lRetVal = TRUE.
+            LEAVE.  
+        END.
+
+        DO WHILE cFunction = 'loadconfig':
+            FIND htmldokumente NO-LOCK 
+                WHERE htmldokumente.company     =         oJsonIdent:GetCharacter('company')
+                AND   htmldokumente.user_name   =         oJsonIdent:GetCharacter('user_name')
+                AND   htmldokumente.form_id     =         oJsonIdent:GetCharacter('form_id')
+                AND   htmldokumente.language_id = INTEGER(oJsonIdent:GetCharacter('language_id')) NO-ERROR.
+            IF NOT AVAILABLE htmldokumente THEN LEAVE.
+MESSAGE 'gefunden'.
+            cFiles = htmldokumente.tables.
+
+            oJsonSelectBoxes = NEW JsonObject().
+            FOR EACH selectboxfields NO-LOCK
+                WHERE selectboxfields.company = htmldokumente.company
+                AND   selectboxfields.program = htmldokumente.form_id:
+                MESSAGE selectboxfields.boxfields.
+                DO ii = 1 TO NUM-ENTRIES(selectboxfields.boxfields, ';'):
+                    cFieldName = ENTRY(ii, selectboxfields.boxfields, ';').
+                    cFileName  = ENTRY(1, cFieldName, '_').
+
+                    IF cFieldName MATCHES('*company*') THEN 
+                    DO:
+                        oJsonBox  = NEW JsonArray().
+                        httBuffer = oSelectboxHandler:getSelboxCompany(cFileName).
+                        httBuffer:WRITE-JSON ('JsonArray', oJsonBox).
+                        oJsonSelectBoxes:ADD(cFieldName, oJsonBox).
+                        NEXT.
+                    END.
+            
+                    IF cFieldName MATCHES('*language_id*') THEN 
+                    DO:
+                        oJsonBox  = NEW JsonArray().
+                        httBuffer = oSelectboxHandler:getSelboxLanguage(cFileName).
+                        httBuffer:WRITE-JSON ('JsonArray', oJsonBox).
+                        oJsonSelectBoxes:ADD(cFieldName, oJsonBox).
+                        NEXT.
+                    END.
+                    
+                /*                    httBuffer = oSelectboxHandler:getSelboxLaguages(). */
+                /*                    oJsonCompanies = NEW JsonArray().                  */
+                /*                    httBuffer:WRITE-JSON ('JsonArray', oJsonLanguages).*/
+                END.
+            END.
+            
+            DO ii = 1 TO NUM-ENTRIES(cFiles, ';'):
+                httBuffer = outilitiesHandler:getData(
+                    INPUT  oJsonIdent            ,
+                    INPUT  ENTRY(ii, cFiles, ';') ,
+                    INPUT  ''        
+                    ).
+                oJsonRecords = NEW JsonArray().
+                httBuffer:WRITE-JSON('JsonArray', oJsonRecords).
+            END.
+
+            oJsonResponse = NEW JsonObject().
+            oJsonResponse:ADD('formTitle', htmldokumente.formtitle).
+            oJsonResponse:ADD('formId'   , htmldokumente.form_id  ).
+
+            oParser   = NEW ObjectModelParser().
+            oJsonData = CAST(oParser:Parse(htmldokumente.htmltext), JsonObject).
+            oJsonSelectedFields = NEW JsonArray().
+            oJsonSelectedFields = oJsonData:GetJsonArray('selectedFields').
+            
+            oJsonResponse:ADD('selectedFields'  , oJsonSelectedFields).
+            oJsonResponse:ADD('selectOptionsFix', oJsonSelectBoxes).
+
+            oJsonResponse:ADD('records', oJsonRecords).            
+            
+            // oJsonResponse:WriteFile('C:\TEMP\loadconfig.json', TRUE).
+            oJsonResponse:WRITE(lcJsonInhalt, FALSE).
+            
+            lRetVal = TRUE.
+            LEAVE.
+        END.
+        
+        DO WHILE cFunction = "getformconfig":
+            FIND htmldokumente NO-LOCK 
+                WHERE htmldokumente.company     = oJsonIdent:GetCharacter('company')
+                AND   htmldokumente.user_name   = oJsonIdent:GetCharacter('user')
+                AND   htmldokumente.form_id     = oJsonIdent:GetCharacter('form_id')
+                AND   htmldokumente.language_id = INTEGER(oJsonIdent:GetCharacter('language_id')) NO-ERROR.
+            IF NOT AVAILABLE htmldokumente THEN LEAVE.
+            
+            oJsonResponse = NEW JsonObject().
+            oJsonResponse:ADD('formTitle'       , htmldokumente.formtitle) NO-ERROR.
+            oJsonResponse:ADD('formId'          , htmldokumente.form_id  ) NO-ERROR.
+            oJsonResponse:ADD('targetCompany'   , oJsonIdent:GetCharacter('company')   ) NO-ERROR.
+            oJsonResponse:ADD('targetUser'      , oJsonIdent:GetCharacter('user')       ) NO-ERROR.
+            oJsonResponse:ADD('targetLanguageId', oJsonIdent:GetCharacter('language_id')) NO-ERROR.
+             
+            oParser   = NEW ObjectModelParser().
+            oJsonData = CAST(oParser:Parse(htmldokumente.htmltext), JsonObject).
+            oJsonSelectedFields = NEW JsonArray().
+            oJsonSelectedFields = oJsonData:GetJsonArray('selectedFields').
+            oJsonResponse:ADD('selectedFields'  , oJsonSelectedFields).
+
+            // oJsonResponse:WriteFile('C:\TEMP\getformconfigresponse.json', TRUE).
+            
+            oJsonResponse:WRITE(lcJsonInhalt, FALSE ).
+
+            lRetVal = TRUE.
+            LEAVE.
+        END.            
+            
+
+        IF NOT lRetVal THEN 
+        DO:
+            oJsonResponse = NEW JsonObject().
+            oJsonResponse:ADD('success', FALSE).
+            oJsonResponse:WRITE(lcJsonInhalt, FALSE).
+        END.
+                
+        cContent-Type   = "application/json".
+        cDefautlCharSet = 'utf-8'.
+
+        oBody = NEW STRING(lcJsonInhalt).
+        WebHandlerUtilities:createHttpResponse(INPUT INTEGER(StatusCodeEnum:OK), INPUT oBody, INPUT cContent-Type, INPUT cDefautlCharSet, INPUT cCorralationID, OUTPUT oResponse).
+//        oResponse:SetHeader(HttpHeaderBuilder:Build(cHeaderCorralationID):Value(cCorralationID):Header).
+
+        oWriter = NEW WebResponseWriter(oResponse).
+        oWriter:Open(). 
+        oWriter:Close(). 
+
+        RETURN 0.
+        
+        CATCH e AS Progress.Lang.Error:
+
+        END CATCH.
+
+        FINALLY:
+
+        END FINALLY.
+
+    END METHOD.
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleNotAllowedMethod(INPUT poRequest AS IWebRequest):
+        DEFINE VARIABLE result AS INTEGER NO-UNDO.
+        MESSAGE "HandleNotAllowedMethod called" VIEW-AS ALERT-BOX.
+        RETURN result.
+    END METHOD.
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleNotImplemented(INPUT poRequest AS IWebRequest):
+        DEFINE VARIABLE result AS INTEGER NO-UNDO.
+        MESSAGE "HandleNotImplemented called" VIEW-AS ALERT-BOX.
+        RETURN result.
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD OVERRIDE PROTECTED INTEGER HandlePost(INPUT poRequest AS IWebRequest):
+        
+        DEFINE VARIABLE oResponse     AS IHttpResponse     NO-UNDO.
+        DEFINE VARIABLE oWriter       AS WebResponseWriter NO-UNDO.
+        DEFINE VARIABLE oJsonData     AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonWebmenu  AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE oJsonMessage  AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonResponse AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oFelder       AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE oFeld         AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oParser       AS ObjectModelParser NO-UNDO.           
+        
+        DEFINE VARIABLE lRetVal       AS LOGICAL           NO-UNDO.
+        DEFINE VARIABLE lcJsonString  AS LONGCHAR          NO-UNDO.
+        DEFINE VARIABLE cJSON         AS LONGCHAR          NO-UNDO.
+        DEFINE VARIABLE i1            AS INTEGER           NO-UNDO.
+        
+        DEFINE VARIABLE cTabellen     AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE ccompany      AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cuser_name    AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE ilanguage_id  AS INTEGER           NO-UNDO.
+        DEFINE VARIABLE cMaskenId     AS CHARACTER         NO-UNDO.
+        
+        lRetVal = WebHandlerUtilities:getJsonFromRequest(INPUT poRequest, OUTPUT oJsonData) NO-ERROR.
+
+        oJsonData:WRITE(lcJsonString, FALSE).
+        // MESSAGE 'ganzer Eingangsstring = ' STRING(lcJsonString).
+            
+        ccompany     = oJsonData:GetCharacter('company' ).
+        cuser_name   = oJsonData:GetCharacter('user_name' ).
+        ilanguage_id = INTEGER(oJsonData:GetCharacter('language_id')).
+
+        // MESSAGE 'HANDLE POST ' ccompany '-' cuser_name '-' ilanguage_id.
+        
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+    DESTRUCTOR PUBLIC formprogramImpl ( ):
+
+    END DESTRUCTOR.
+
+END CLASS.

+ 519 - 0
admin/menudesignerImpl.cls

@@ -0,0 +1,519 @@
+ 
+/*------------------------------------------------------------------------
+   File        : adresse_dict
+   Purpose     : 
+   Syntax      : 
+   Description : 
+   Author(s)   : walter.riechsteiner
+   Created     : Thu Jun 26 13:56:20 CEST 2025
+   Notes       : 
+ ----------------------------------------------------------------------*/
+ 
+BLOCK-LEVEL ON ERROR UNDO, THROW.
+
+USING OpenEdge.Core.String FROM PROPATH.
+USING OpenEdge.Net.HTTP.IHttpResponse FROM PROPATH.
+USING OpenEdge.Net.HTTP.StatusCodeEnum FROM PROPATH.
+USING OpenEdge.Web.IWebRequest FROM PROPATH.
+USING OpenEdge.Web.WebHandler FROM PROPATH.
+USING OpenEdge.Web.WebResponseWriter FROM PROPATH.
+USING Progress.Json.ObjectModel.JsonObject FROM PROPATH.
+USING Progress.Json.ObjectModel.JsonArray FROM PROPATH.
+USING Progress.Json.ObjectModel.ObjectModelParser FROM PROPATH.
+USING src.ch.adprime.gemis.WebHandlerUtilities FROM PROPATH.
+USING utilities.utilitiesHandler FROM PROPATH.
+
+CLASS admin.menudesignerImpl INHERITS WebHandler: 
+
+    DEFINE VARIABLE ccompany          AS CHARACTER        NO-UNDO.
+    DEFINE VARIABLE cuser_name        AS CHARACTER        NO-UNDO.
+    DEFINE VARIABLE cAnzeigeName      AS CHARACTER        NO-UNDO.
+    DEFINE VARIABLE ilanguage_id      AS INTEGER          NO-UNDO.
+    DEFINE VARIABLE cSessionToken     AS CHARACTER        NO-UNDO.
+    
+    DEFINE VARIABLE outilitiesHandler AS utilitiesHandler NO-UNDO.
+    
+    DEFINE TEMP-TABLE tcompanies
+        SERIALIZE-NAME 'companies'
+        FIELD company      AS CHARACTER SERIALIZE-NAME 'company'
+        FIELD company_Name AS CHARACTER SERIALIZE-NAME 'company_name'
+        FIELD lselected    AS LOGICAL   SERIALIZE-NAME 'selected'
+        .
+    DEFINE VARIABLE htcompanies AS HANDLE NO-UNDO.
+        
+    DEFINE TEMP-TABLE tusers
+        FIELD user_name    AS CHARACTER 
+        FIELD display_name AS CHARACTER
+        .
+    DEFINE VARIABLE htusers AS HANDLE NO-UNDO.
+    
+    DEFINE TEMP-TABLE tlanguages
+        FIELD language_id   AS INTEGER 
+        FIELD language_name AS CHAR
+        .
+    DEFINE VARIABLE htlanguages AS HANDLE NO-UNDO.
+        
+    DEFINE TEMP-TABLE tLevel1
+        SERIALIZE-NAME ''
+        FIELD menu_id      AS INTEGER 
+        FIELD menu_text    AS CHARACTER 
+        FIELD menu_link    AS CHARACTER
+        FIELD level1       AS INTEGER   SERIALIZE-NAME 'level1'
+        FIELD level2       AS INTEGER   SERIALIZE-NAME 'level2'
+        FIELD level3       AS INTEGER   SERIALIZE-NAME 'level3'
+        FIELD openMode     AS CHARACTER 
+        FIELD admin        AS LOGICAL 
+        FIELD level1_recid AS RECID     SERIALIZE-HIDDEN 
+        .
+    DEFINE TEMP-TABLE tLevel2
+        SERIALIZE-NAME 'children'
+        FIELD level1_recid AS RECID     SERIALIZE-HIDDEN 
+        FIELD menu_id      AS INTEGER 
+        FIELD menu_text    AS CHARACTER 
+        FIELD menu_link    AS CHARACTER 
+        FIELD level1       AS INTEGER   SERIALIZE-NAME 'level1'
+        FIELD level2       AS INTEGER   SERIALIZE-NAME 'level2'
+        FIELD level3       AS INTEGER   SERIALIZE-NAME 'level3'
+        FIELD openMode     AS CHARACTER 
+        FIELD admin        AS LOGICAL 
+        FIELD level2_recid AS RECID     SERIALIZE-HIDDEN 
+        .
+    DEFINE TEMP-TABLE tLevel3
+        SERIALIZE-NAME 'children'
+        FIELD level2_recid AS RECID     SERIALIZE-HIDDEN 
+        FIELD menu_id      AS INTEGER 
+        FIELD menu_text    AS CHARACTER 
+        FIELD menu_link    AS CHARACTER 
+        FIELD level1       AS INTEGER   SERIALIZE-NAME 'level1'
+        FIELD level2       AS INTEGER   SERIALIZE-NAME 'level2'
+        FIELD level3       AS INTEGER   SERIALIZE-NAME 'level3'
+        FIELD openMode     AS CHARACTER 
+        FIELD admin        AS LOGICAL 
+        FIELD level3_recid AS RECID     SERIALIZE-HIDDEN 
+        .
+    DEFINE DATASET menu_structur
+        SERIALIZE-NAME 'menuItem'
+        FOR tLevel1, tLevel2, tLevel3
+
+        PARENT-ID-RELATION RELATION1 FOR tLevel1, tLevel2
+        PARENT-ID-FIELD level1_recid
+    
+        PARENT-ID-RELATION RELATION2 FOR tLevel2, tLevel3
+        PARENT-ID-FIELD level2_recid
+        .
+    DEFINE VARIABLE hDSmenu_structur AS HANDLE NO-UNDO.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleGet (INPUT poRequest AS IWebRequest ):
+        DEFINE VARIABLE oResponse       AS IHttpResponse     NO-UNDO.         
+        DEFINE VARIABLE oWriter         AS WebResponseWriter NO-UNDO.
+        DEFINE VARIABLE oBody           AS String            NO-UNDO.
+        DEFINE VARIABLE cDefautlCharSet AS CHARACTER         NO-UNDO INIT 'UTF-8'.
+        DEFINE VARIABLE oParser         AS ObjectModelParser NO-UNDO.           
+        DEFINE VARIABLE cCorralationID  AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cContent-Type   AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE lcJsonInhalt    AS LONGCHAR          NO-UNDO.
+        DEFINE VARIABLE lOk             AS LOGICAL           NO-UNDO.
+        DEFINE VARIABLE ii              AS INTEGER           NO-UNDO.
+        DEFINE VARIABLE dDateTime       AS DATETIME          NO-UNDO.
+        DEFINE VARIABLE cDateTime       AS CHARACTER         NO-UNDO.
+        
+        DEFINE VARIABLE oJsonWebmenu    AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonResponse   AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonCompanies  AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE oJsonUsers      AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE oJsonLanguages  AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE oJsonMenu       AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE oJsonData       AS JsonObject        NO-UNDO.
+        
+        DEFINE VARIABLE ccompany        AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cuser_name      AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cnewuser_name   AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE rtlevel1        AS RECID             NO-UNDO.
+        DEFINE VARIABLE rtlevel2        AS RECID             NO-UNDO.
+        DEFINE VARIABLE ilanguage_id    AS INTEGER           NO-UNDO.
+        DEFINE VARIABLE cFunction       AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE lRetVal         AS LOGICAL           NO-UNDO.
+        
+        DEFINE BUFFER bwebmenu FOR webmenu.
+        
+        outilitiesHandler = NEW utilitiesHandler().
+        
+        outilitiesHandler:getHeaderData(
+            INPUT  poRequest    ,
+            OUTPUT ccompany     ,
+            OUTPUT cuser_name   ,
+            OUTPUT cAnzeigeName ,
+            OUTPUT ilanguage_id ,
+            OUTPUT cSessionToken
+            ).
+        
+        cFunction    =         poRequest:URI:GetQueryValue("function")      NO-ERROR.
+        ccompany     =         poRequest:URI:GetQueryValue("company")       NO-ERROR.
+        cuser_name   =         poRequest:URI:GetQueryValue("user_name")     NO-ERROR.
+        ilanguage_id = INTEGER(poRequest:URI:GetQueryValue("language_id"))  NO-ERROR.
+        MESSAGE 'GET company = ' ccompany 'user_name = ' cuser_name 'Sprache = ' ilanguage_id 'Function = ' cFunction 'Session-Token = ' cSessiontoken.
+        
+        lRetVal = FALSE.
+        DO WHILE cFunction = 'init':
+            EMPTY TEMP-TABLE tcompanies.
+            FOR EACH companies NO-LOCK WHERE companies.active:
+                CREATE  tcompanies.
+                BUFFER-COPY companies TO tcompanies.
+                ASSIGN 
+                    tcompanies.lselected = (IF companies.company = ccompany THEN TRUE ELSE FALSE).
+            END.
+            
+            EMPTY TEMP-TABLE tusers.
+            FOR EACH users NO-LOCK WHERE users.active:
+                CREATE  tusers.
+                BUFFER-COPY users TO tusers.
+            END.
+            
+            EMPTY TEMP-TABLE tlanguages.
+            FOR EACH languages NO-LOCK:
+                CREATE  tlanguages.
+                BUFFER-COPY languages TO tlanguages.
+            END.
+            
+            oJsonResponse   = NEW JsonObject().
+            oJsonCompanies  = NEW JsonArray().
+            oJsonUsers      = NEW JsonArray().
+            oJsonLanguages  = NEW JsonArray().
+            
+            htcompanies = TEMP-TABLE tcompanies:DEFAULT-BUFFER-HANDLE.
+            htusers     = TEMP-TABLE tusers    :DEFAULT-BUFFER-HANDLE.
+            htlanguages = TEMP-TABLE tlanguages:DEFAULT-BUFFER-HANDLE.
+            
+            htcompanies:WRITE-JSON('JsonArray', oJsonCompanies ).
+            htusers    :WRITE-JSON('JsonArray', oJsonUsers     ).
+            htlanguages:WRITE-JSON('JsonArray', oJsonLanguages ).
+            
+            oJsonResponse:ADD('companies', oJsonCompanies).
+            oJsonResponse:ADD('users'    , oJsonUsers    ).
+            oJsonResponse:ADD('languages', oJsonLanguages).
+            
+            oJsonResponse:WRITE(lcJsonInhalt, FALSE).
+            
+            MESSAGE STRING(lcJsonInhalt).
+            
+            lRetVal = TRUE.
+            LEAVE.
+        END.
+
+        cnewuser_name = cuser_name.        
+        DO WHILE cFunction = 'load':
+            hDSmenu_structur = DATASET menu_structur:HANDLE.
+            
+            EMPTY TEMP-TABLE tlevel1.
+            EMPTY TEMP-TABLE tlevel2.
+            EMPTY TEMP-TABLE tlevel3.
+            
+            DO WHILE TRUE.
+                FIND FIRST webmenu NO-LOCK
+                    WHERE webmenu.company   = ccompany
+                    AND   webmenu.user_name = cnewuser_name NO-ERROR.
+                IF AVAILABLE webmenu        THEN LEAVE.
+                IF cnewuser_name = 'Admin' THEN LEAVE.
+            
+                cnewuser_name = 'Admin'.
+            END.
+        
+            FOR EACH webmenu NO-LOCK
+                WHERE webmenu.company   = ccompany
+                AND   webmenu.user_name = cnewuser_name
+                AND   webmenu.level1    > 0 :
+                
+                IF webmenu.level2 = 0 THEN 
+                DO:
+                    CREATE  tlevel1.
+                    ASSIGN 
+                        tlevel1.level1_recid = RECID(tLevel1)
+                        tlevel1.menu_id      = webmenu.level1
+                        tlevel1.menu_text    = webmenu.menu_title
+                        tlevel1.menu_link    = webmenu.menu_link
+                        tLevel1.level1       = webmenu.level1
+                        tLevel1.level2       = webmenu.level2
+                        tLevel1.level3       = webmenu.level3
+                        tlevel1.openMode     = webmenu.openmode
+                        tlevel1.admin        = webmenu.ladmin
+                        
+                        rtlevel1             = RECID(tlevel1).
+                    NEXT.
+                END.
+
+                IF webmenu.level3 = 0 THEN 
+                DO:
+                    CREATE  tlevel2.
+                    ASSIGN 
+                        tlevel2.level1_recid = rtlevel1
+                        tlevel2.level2_recid = RECID(tLevel2)
+                        tlevel2.menu_id      = webmenu.level2
+                        tlevel2.menu_text    = webmenu.menu_title
+                        tlevel2.menu_link    = webmenu.menu_link
+                        tLevel2.level1       = webmenu.level1
+                        tLevel2.level2       = webmenu.level2
+                        tLevel2.level3       = webmenu.level3
+                        tlevel2.openmode     = webmenu.openmode
+                        tlevel2.admin        = webmenu.ladmin
+
+                        rtlevel2             = RECID(tlevel2).
+                    NEXT.
+                END.
+                CREATE  tlevel3.
+                ASSIGN 
+                    tlevel3.level2_recid = rtlevel2
+                    tlevel3.level3_recid = RECID(tLevel3)
+                    tlevel3.menu_id      = webmenu.level3
+                    tlevel3.menu_text    = webmenu.menu_title
+                    tlevel3.menu_link    = webmenu.menu_link
+                    tLevel3.level1       = webmenu.level1
+                    tLevel3.level2       = webmenu.level2
+                    tLevel3.level3       = webmenu.level3
+                    tlevel3.openMode     = webmenu.openmode
+                    tlevel3.admin        = webmenu.ladmin
+                    .
+            END.
+
+            oParser       = NEW ObjectModelParser().
+            oJsonResponse = NEW JsonObject().
+            oJsonMenu     = NEW JsonArray ().
+            oJsonData     = NEW JsonObject().
+            oJsonData:READ(hDSmenu_structur).
+            
+            lcJsonInhalt = oJsonData:GetJsonText('menuItem').
+            
+            ii = INDEX(lcJsonInhalt, '[').
+            lcJsonInhalt = SUBSTRING(lcJsonInhalt, ii).
+            ii = R-INDEX(lcJsonInhalt, ']').
+            lcJsonInhalt = SUBSTRING(lcJsonInhalt,01,ii).
+        
+            oJsonMenu = CAST(oParser:Parse(lcJsonInhalt), JsonArray) NO-ERROR.
+            oJsonResponse:ADD('menuItems', oJsonMenu).
+            oJsonResponse:WRITE(lcJsonInhalt, FALSE).
+            
+            MESSAGE 'Menustruktur = '  STRING(lcJsonInhalt).
+            
+            lRetVal = TRUE.
+            LEAVE.
+        END.
+
+        IF NOT lRetVal THEN 
+        DO:
+            oJsonResponse = NEW JsonObject().
+            oJsonResponse:ADD('success', FALSE).
+            oJsonResponse:WRITE(lcJsonInhalt, FALSE).
+        END.
+                
+        cContent-Type   = "application/json".
+        cDefautlCharSet = 'utf-8'.
+         
+        oBody = NEW STRING(lcJsonInhalt).
+        WebHandlerUtilities:createHttpResponse(INPUT INTEGER(StatusCodeEnum:OK), INPUT oBody, INPUT cContent-Type, INPUT cDefautlCharSet, INPUT cCorralationID, OUTPUT oResponse).
+//        oResponse:SetHeader(HttpHeaderBuilder:Build(cHeaderCorralationID):Value(cCorralationID):Header).
+
+        
+        oWriter = NEW WebResponseWriter(oResponse).
+        oWriter:Open(). 
+        oWriter:Close(). 
+
+        RETURN 0.
+        
+        CATCH e AS Progress.Lang.Error:
+
+        END CATCH.
+
+        FINALLY:
+
+        END FINALLY.
+
+    END METHOD.
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleNotAllowedMethod(INPUT poRequest AS IWebRequest):
+        DEFINE VARIABLE result AS INTEGER NO-UNDO.
+        MESSAGE "HandleNotAllowedMethod called" VIEW-AS ALERT-BOX.
+        RETURN result.
+    END METHOD.
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleNotImplemented(INPUT poRequest AS IWebRequest):
+        DEFINE VARIABLE result AS INTEGER NO-UNDO.
+        MESSAGE "HandleNotImplemented called" VIEW-AS ALERT-BOX.
+        RETURN result.
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD OVERRIDE PROTECTED INTEGER HandlePost(INPUT poRequest AS IWebRequest):
+        
+        DEFINE VARIABLE oResponse     AS IHttpResponse     NO-UNDO.
+        DEFINE VARIABLE oWriter       AS WebResponseWriter NO-UNDO.
+        DEFINE VARIABLE oJsonData     AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonWebmenu  AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE oJsonMessage  AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonResponse AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oFelder       AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE oFeld         AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oParser       AS ObjectModelParser NO-UNDO.           
+        
+        DEFINE VARIABLE lRetVal       AS LOGICAL           NO-UNDO.
+        DEFINE VARIABLE lcJsonString  AS LONGCHAR          NO-UNDO.
+        DEFINE VARIABLE cJSON         AS LONGCHAR          NO-UNDO.
+        DEFINE VARIABLE i1            AS INTEGER           NO-UNDO.
+        
+        DEFINE VARIABLE cTabellen     AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE ccompany      AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cuser_name    AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE ilanguage_id  AS INTEGER           NO-UNDO.
+        DEFINE VARIABLE cMaskenId     AS CHARACTER         NO-UNDO.
+        
+        lRetVal = WebHandlerUtilities:getJsonFromRequest(INPUT poRequest, OUTPUT oJsonData) NO-ERROR.
+
+        oJsonData:WRITE(lcJsonString, FALSE).
+        MESSAGE 'ganzer Eingangsstring = ' STRING(lcJsonString).
+            
+        ccompany     = oJsonData:GetCharacter('company' ).
+        cuser_name   = oJsonData:GetCharacter('user_name' ).
+        ilanguage_id = INTEGER(oJsonData:GetCharacter('language_id')).
+
+        //  Aufbereiten Json-Struktur für READ-JSON in DATASET 
+        lcJsonString = oJsonData:GetJsonText('menuItems').
+        lcJsonString = CHR(123)     /*  {   */
+            + ' "menuItem": '
+            + CHR(123)              /*  {   */
+            + '"": '
+            + lcJsonString
+            + CHR(125)              /*  }   */
+            + CHR(125).             /*  }   */
+
+        hDSmenu_structur = DATASET menu_structur:HANDLE.
+        hDSmenu_structur:READ-JSON ('LONGCHAR', lcJsonString, 'empty') NO-ERROR.
+
+        lRetVal = FALSE.
+        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
+            
+            DEFINE VARIABLE ilevel2 AS INTEGER NO-UNDO.
+            DEFINE VARIABLE ilevel3 AS INTEGER NO-UNDO.
+            
+            //  Level2 und level3 neu in 10er-Schritten durchnummerieren
+            
+            FOR EACH tlevel1:
+                
+                ilevel2 = 0.
+                FOR EACH tlevel2
+                    WHERE tLevel2.level1 = tlevel1.level1:
+                        
+                    ilevel3 = 0.
+                    FOR EACH tlevel3
+                        WHERE tLevel3.level1 = tlevel1.level1
+                        AND   tLevel3.level2 = tlevel2.level2:
+                            
+                        ilevel3        = ilevel3 + 10.
+                        tlevel3.level3 = ilevel3.
+                    END.
+                        
+                    iLevel2        = ilevel2 + 10.
+                    tlevel2.level2 = ilevel2.
+                END.
+                 
+            END.
+            
+            FOR EACH webmenu
+                WHERE webmenu.company   = ccompany
+                AND   webmenu.user_name = cuser_name:
+                DELETE webmenu.
+            END.
+                    
+            FOR EACH tlevel1:
+                CREATE  webmenu.
+                ASSIGN 
+                    webmenu.company    = ccompany
+                    webmenu.user_name  = cuser_name
+                    webmenu.level1     = tlevel1.level1
+                    webmenu.level2     = 0
+                    webmenu.level3     = 0
+                    webmenu.menu_title = tlevel1.menu_text
+                    webmenu.menu_link  = tlevel1.menu_link
+                    webmenu.ladmin     = tlevel1.admin
+                    webmenu.openmode   = tlevel1.openMode
+                    webmenu.created_at = NOW 
+                    webmenu.updated_at = NOW 
+                    .
+            END. 
+            FOR EACH tlevel2:
+                CREATE  webmenu.
+                ASSIGN 
+                    webmenu.company    = ccompany
+                    webmenu.user_name  = cuser_name
+                    webmenu.level1     = tlevel2.level1
+                    webmenu.level2     = tlevel2.level2
+                    webmenu.level3     = 0
+                    webmenu.menu_title = tlevel2.menu_text
+                    webmenu.menu_link  = tlevel2.menu_link
+                    webmenu.ladmin     = tlevel2.admin
+                    webmenu.openmode   = tlevel2.openMode
+                    webmenu.created_at = NOW 
+                    webmenu.updated_at = NOW 
+                    .
+            END. 
+            FOR EACH tlevel3:
+                CREATE  webmenu.
+                ASSIGN 
+                    webmenu.company    = ccompany
+                    webmenu.user_name  = cuser_name
+                    webmenu.level1     = tlevel3.level1
+                    webmenu.level2     = tlevel3.level2
+                    webmenu.level3     = tlevel3.level3
+                    webmenu.menu_title = tlevel3.menu_text
+                    webmenu.menu_link  = tlevel3.menu_link
+                    webmenu.ladmin     = tlevel3.admin
+                    webmenu.openmode   = tlevel3.openMode
+                    webmenu.created_at = NOW 
+                    webmenu.updated_at = NOW 
+                    .
+            END.
+            lRetVal = TRUE. 
+            LEAVE.            
+        END.
+                
+        oResponse             = NEW OpenEdge.Web.WebResponse().
+        oResponse:StatusCode  = INTEGER(StatusCodeEnum:OK).
+        oResponse:ContentType = "application/json;charset=utf-8".
+        oWriter               = NEW WebResponseWriter(oResponse).
+                    
+        oJsonMessage = NEW JsonObject().
+        IF lRetVal THEN 
+        DO:
+            oJsonMessage:ADD('success', TRUE).
+            oJsonMessage:WRITE(lcJsonString, TRUE).
+        END.
+        ELSE 
+        DO:
+            oJsonMessage:ADD('success', TRUE).
+            oJsonMessage:ADD('message', 'Fehler beim erstellen der Menu-Struktur').
+            oJsonMessage:WRITE(lcJsonString, FALSE).
+        END.
+        MESSAGE 'Rückmeldung ' STRING(lcJsonString).
+                        
+        oWriter:Open().
+        oWriter:Write(lcJsonString).
+        oWriter:Close().
+            
+        CATCH e AS Progress.Lang.Error:
+            
+        END CATCH.
+            
+        FINALLY:
+        /*            DELETE OBJECT oJsonConfig. */
+        /*            DELETE OBJECT oJsonMessage.*/
+        END FINALLY.
+
+    END METHOD.
+
+END CLASS.

+ 318 - 0
admin/programgeneratorImpl.cls

@@ -0,0 +1,318 @@
+/*------------------------------------------------------------------------
+   File        : programgeneratorImpl
+   Purpose     : 
+   Syntax      : 
+   Description : 
+   Author(s)   : walter.riechsteiner
+   Created     : Wed Nov 19 13:23:38 CET 2025
+   Notes       : 
+ ----------------------------------------------------------------------*/
+
+
+BLOCK-LEVEL ON ERROR UNDO, THROW.
+
+USING OpenEdge.Core.String FROM PROPATH.
+USING OpenEdge.Net.HTTP.IHttpResponse FROM PROPATH.
+USING OpenEdge.Net.HTTP.StatusCodeEnum FROM PROPATH.
+USING OpenEdge.Web.IWebRequest FROM PROPATH.
+USING OpenEdge.Web.WebResponseWriter FROM PROPATH.
+USING Progress.Json.ObjectModel.ObjectModelParser FROM PROPATH.
+USING Progress.Json.ObjectModel.JsonObject FROM PROPATH.
+USING Progress.Json.ObjectModel.JsonArray FROM PROPATH.
+USING src.ch.adprime.gemis.WebHandlerUtilities FROM PROPATH.
+USING utilities.utilitiesHandler FROM PROPATH.
+USING utilities.selectboxHandler FROM PROPATH.
+USING OpenEdge.Web.WebHandler FROM PROPATH.
+
+CLASS admin.programgeneratorImpl INHERITS WebHandler: 
+
+    DEFINE VARIABLE ccompany          AS CHARACTER        NO-UNDO.
+    DEFINE VARIABLE cuser_name        AS CHARACTER        NO-UNDO.
+    DEFINE VARIABLE cAnzeigeName      AS CHARACTER        NO-UNDO.
+    DEFINE VARIABLE ilanguage_id      AS INTEGER          NO-UNDO.
+    DEFINE VARIABLE cSessionToken     AS CHARACTER        NO-UNDO.
+    
+    DEFINE VARIABLE outilitiesHandler AS utilitiesHandler NO-UNDO.
+
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleGet (INPUT poRequest AS IWebRequest ):
+        DEFINE VARIABLE oResponse       AS IHttpResponse     NO-UNDO.         
+        DEFINE VARIABLE oWriter         AS WebResponseWriter NO-UNDO.
+        DEFINE VARIABLE oBody           AS String            NO-UNDO.
+        DEFINE VARIABLE cDefautlCharSet AS CHARACTER         NO-UNDO INIT 'UTF-8'.
+        DEFINE VARIABLE oParser         AS ObjectModelParser NO-UNDO.           
+        DEFINE VARIABLE cCorralationID  AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cContent-Type   AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE lcJsonInhalt    AS LONGCHAR          NO-UNDO.
+        
+        DEFINE VARIABLE oJsonResponse   AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonIdent      AS JsonObject        NO-UNDO.
+        
+        DEFINE VARIABLE ccompany        AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cuser_name      AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE ilanguage_id    AS INTEGER           NO-UNDO.
+        DEFINE VARIABLE cFunction       AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cForm_Id        AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cProgram        AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE lRetVal         AS LOGICAL           NO-UNDO.
+        DEFINE VARIABLE ii              AS INTEGER           NO-UNDO.
+        DEFINE VARIABLE i1              AS INTEGER           NO-UNDO.
+        DEFINE VARIABLE cQueryString    AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cQueryPairs     AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cQueryKey       AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cQueryValue     AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cProgUser       AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE lcProgramCode   AS LONGCHAR          NO-UNDO.
+        
+        outilitiesHandler = NEW utilitiesHandler().
+        
+        cForm_Id = poRequest:URI:GetQueryValue("progname") NO-ERROR.
+        
+        outilitiesHandler:getHeaderData(
+            INPUT  poRequest    ,
+            OUTPUT ccompany     ,
+            OUTPUT cuser_name   ,
+            OUTPUT cAnzeigeName ,
+            OUTPUT ilanguage_id ,
+            OUTPUT cSessionToken
+            ).
+        
+        oJsonIdent = NEW JsonObject().
+        oJsonIdent:ADD('company'     , ccompany     ).
+        oJsonIdent:ADD('user_name'   , cuser_name   ).
+        oJsonIdent:ADD('language_id' , iLanguage_id ).
+        oJsonIdent:ADD('sessionToken', cSessionToken).
+        
+        cQueryString = STRING(poRequest:GetContextValue("QUERY_STRING"))    NO-ERROR.
+        DO ii = 1 TO NUM-ENTRIES(cQueryString, '&'):
+            cQueryPairs = ENTRY(ii, cQueryString, '&').
+            cQueryKey   = ENTRY(1 , cQueryPairs , '=').
+            cQueryValue = ENTRY(2 , cQueryPairs , '=').
+            IF oJsonIdent:Has(cQueryKey) THEN oJsonIdent:SET(cQueryKey, cQueryValue) NO-ERROR.
+            ELSE                              oJsonIdent:ADD(cQueryKey, cQueryValue) NO-ERROR.
+        END.
+        
+        // MESSAGE 'oJsonIdent = ' STRING(oJsonIdent:write(lcJsonInhalt)).
+        
+        cFunction = oJsonIdent:GetCharacter('function') NO-ERROR.
+        cProgram  = oJsonIdent:GetCharacter('program_name') NO-ERROR.
+        
+        cProgUser = cuser_name.
+        lRetVal   = FALSE.
+        // MESSAGE 'company = ' ccompany '- proguser = ' cproguser '- ilanguage_id = ' iLanguage_id '- program = ' cprogram. 
+        DO WHILE TRUE:
+            FIND FIRST htmldokumente NO-LOCK 
+                WHERE htmldokumente.company     = ccompany
+                AND   htmldokumente.user_name   = cProgUser
+                AND   htmldokumente.language_id = iLanguage_id
+                AND   htmldokumente.program     = cProgram NO-ERROR.
+            
+            IF NOT AVAILABLE htmldokumente THEN 
+            DO:
+                IF cProgUser = 'admin' THEN LEAVE.
+                cProgUser = 'admin'.
+                NEXT.
+            END.
+            MESSAGE 'gefunden mit user ' cproguser.
+            COPY-LOB htmldokumente.htmlprogram TO lcProgramCode.
+            /*            lcProgramCode = REPLACE(lcProgramCode, '"'    , '\"').*/
+            /*            lcProgramCode = REPLACE(lcProgramCode, CHR(13), '\r').*/
+            /*            lcProgramCode = REPLACE(lcProgramCode, CHR(10), '\n').*/
+            /*            lcProgramCode = REPLACE(lcProgramCode, CHR(09), '\t').*/
+            
+            lRetVal = TRUE.
+            LEAVE.
+        END.
+        
+        // MESSAGE 'oJsonIdent = ' STRING(oJsonIdent:GetJsonText()).
+
+        oJsonResponse = NEW JsonObject().
+        oJsonResponse:ADD('program_name', cProgram).
+        oJsonResponse:ADD('form_id'     , cProgram).
+        oJsonResponse:ADD('program_code', lcprogramcode).
+        oJsonResponse:ADD('created_at'  , ISO-DATE(htmldokumente.created_at)).
+        /*        oJsonResponse:ADD('program_code', lcprogramcode).*/
+        
+        // oJsonResponse:WriteFile('C:\Temp\programmgenerator.json').
+        oJsonResponse:WRITE(lcJsonInhalt, FALSE).
+
+        IF NOT lRetVal THEN 
+        DO:
+            oJsonResponse = NEW JsonObject().
+            oJsonResponse:ADD('success', FALSE).
+            oJsonResponse:WRITE(lcJsonInhalt, FALSE).
+        END.
+                
+        cContent-Type   = "application/json".
+        cDefautlCharSet = 'utf-8'.
+
+        oBody = NEW STRING(lcJsonInhalt).
+        WebHandlerUtilities:createHttpResponse(INPUT INTEGER(StatusCodeEnum:OK), INPUT oBody, INPUT cContent-Type, INPUT cDefautlCharSet, INPUT cCorralationID, OUTPUT oResponse).
+//        oResponse:SetHeader(HttpHeaderBuilder:Build(cHeaderCorralationID):Value(cCorralationID):Header).
+
+        
+        oWriter = NEW WebResponseWriter(oResponse).
+        oWriter:Open(). 
+        oWriter:Close(). 
+
+        RETURN 0.
+        
+        CATCH e AS Progress.Lang.Error:
+
+        END CATCH.
+
+        FINALLY:
+
+        END FINALLY.
+
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD OVERRIDE PROTECTED INTEGER HandlePost(INPUT poRequest AS IWebRequest):
+        
+        DEFINE VARIABLE oResponse         AS IHttpResponse     NO-UNDO.
+        DEFINE VARIABLE oWriter           AS WebResponseWriter NO-UNDO.
+        DEFINE VARIABLE oJsonData         AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonMessage      AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonResponse     AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oParser           AS ObjectModelParser NO-UNDO.
+        DEFINE VARIABLE oJsonIdent        AS JsonObject        NO-UNDO.           
+        
+        DEFINE VARIABLE lRetVal           AS LOGICAL           NO-UNDO.
+        DEFINE VARIABLE lcJsonString      AS LONGCHAR          NO-UNDO.
+        DEFINE VARIABLE cJSON             AS LONGCHAR          NO-UNDO.
+        DEFINE VARIABLE i1                AS INTEGER           NO-UNDO.
+        
+        DEFINE VARIABLE ccompany          AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cuser_name        AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE ilanguage_id      AS INTEGER           NO-UNDO.
+        DEFINE VARIABLE cProgram          AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cFormId           AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cFunction         AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cTargetUser       AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE iTargetLanguageId AS INTEGER           NO-UNDO.
+        DEFINE VARIABLE cTargetCompany    AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cNames            AS CHARACTER         NO-UNDO EXTENT.
+        DEFINE VARIABLE cName             AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE lcBase64_code     AS LONGCHAR          NO-UNDO.
+        DEFINE VARIABLE lcProgramCode     AS LONGCHAR          NO-UNDO.
+        DEFINE VARIABLE mDecodedCode      AS MEMPTR            NO-UNDO.
+        
+        lRetVal = WebHandlerUtilities:getJsonFromRequest(INPUT poRequest, OUTPUT oJsonData) NO-ERROR.
+        
+        IF oJsonData:has('program_code_base64') THEN 
+        DO:
+            lcBase64_code = oJsonData:GetLongchar("program_code_base64").
+            mDecodedCode  = BASE64-DECODE(lcBase64_code).
+            IF GET-SIZE(mDecodedCode) > 0 THEN 
+            DO:
+                COPY-LOB FROM mDecodedCode TO lcProgramCode CONVERT TARGET CODEPAGE "UTF-8".
+                oJsonData:Remove('program_code_base64').
+            END.
+        END.
+        IF oJsonData:has('program_code') THEN 
+        DO:
+            lcProgramcode = oJsonData:GetLongchar("program_code4").
+            oJsonData:Remove('program_code_base64').
+        END.
+        
+            
+        outilitiesHandler = NEW utilitiesHandler().
+        
+        outilitiesHandler:getHeaderData(
+            INPUT  poRequest    ,
+            OUTPUT ccompany     ,
+            OUTPUT cuser_name   ,
+            OUTPUT cAnzeigeName ,
+            OUTPUT ilanguage_id ,
+            OUTPUT cSessionToken
+            ).
+
+        cFunction         =         oJsonData:GetCharacter('function').        
+        cProgram          =         oJsonData:GetCharacter('program_name').        
+        cFormId           =         oJsonData:GetCharacter('form_id').        
+        cTargetUser       =         oJsonData:GetCharacter('target_user').        
+        iTargetLanguageId = INTEGER(oJsonData:GetCharacter('target_language_id')).
+        cTargetCompany    =         oJsonData:GetCharacter('target_company' ).
+
+        lRetVal = FALSE.
+        REPEAT TRANSACTION WHILE cFunction = 'save' ON ERROR UNDO, LEAVE:
+            FIND htmldokumente  
+                WHERE htmldokumente.company     = cTargetCompany
+                AND   htmldokumente.user_name   = cTargetUser
+                AND   htmldokumente.form_id     = cFormId
+                AND   htmldokumente.language_id = iTargetLanguageId NO-ERROR.
+            IF NOT AVAILABLE htmldokumente THEN LEAVE.
+            
+            ASSIGN
+                htmldokumente.program = cProgram.
+            COPY-LOB lcProgramCode TO htmldokumente.htmlprogram.
+            RELEASE htmldokumente.
+            
+            lRetVal = TRUE.    
+            LEAVE.
+        END.
+                    
+        oResponse             = NEW OpenEdge.Web.WebResponse().
+        oResponse:StatusCode  = INTEGER(StatusCodeEnum:OK).
+        oResponse:ContentType = "application/json;charset=utf-8".
+        oWriter               = NEW WebResponseWriter(oResponse).
+                        
+        oJsonMessage = NEW JsonObject().
+        IF lRetVal THEN 
+        DO:
+            oJsonMessage:ADD('success', TRUE).
+            oJsonMessage:WRITE(lcJsonString, TRUE).
+        END.
+        ELSE 
+        DO:
+            oJsonMessage:ADD('success', TRUE).
+            oJsonMessage:ADD('message', 'Fehler beim erstellen der Menu-Struktur').
+            oJsonMessage:WRITE(lcJsonString, FALSE).
+        END.
+        // MESSAGE 'Rückmeldung ' STRING(lcJsonString).
+                            
+        oWriter:Open().
+        oWriter:Write(lcJsonString).
+        oWriter:Close().
+    
+        RETURN 0.
+    
+        CATCH e AS Progress.Lang.Error:
+                
+        END CATCH.
+                
+        FINALLY:
+        /*            DELETE OBJECT oJsonConfig. */
+        /*            DELETE OBJECT oJsonMessage.*/
+        END FINALLY.
+
+    END METHOD.
+    
+    
+    METHOD OVERRIDE PROTECTED INTEGER HandleNotAllowedMethod(INPUT poRequest AS IWebRequest):
+        DEFINE VARIABLE result AS INTEGER NO-UNDO.
+        MESSAGE "HandleNotAllowedMethod called" VIEW-AS ALERT-BOX.
+        RETURN result.
+    END METHOD.
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleNotImplemented(INPUT poRequest AS IWebRequest):
+        DEFINE VARIABLE result AS INTEGER NO-UNDO.
+        MESSAGE "HandleNotImplemented called" VIEW-AS ALERT-BOX.
+        RETURN result.
+    END METHOD.
+
+    DESTRUCTOR PUBLIC programgeneratorImpl ( ):
+
+    END DESTRUCTOR.
+
+END CLASS.

+ 637 - 0
admin/usersHandler.cls

@@ -0,0 +1,637 @@
+ 
+/*------------------------------------------------------------------------
+   File        : usersHandler
+   Purpose     : 
+   Syntax      : 
+   Description : 
+   Author(s)   : walter.riechsteiner
+   Created     : Fri Nov 21 11:31:01 CET 2025
+   Notes       : 
+ ----------------------------------------------------------------------*/
+
+
+BLOCK-LEVEL ON ERROR UNDO, THROW.
+
+USING Progress.Json.ObjectModel.JsonObject FROM PROPATH.
+USING Progress.Json.ObjectModel.JsonArray FROM PROPATH.
+USING utilities.utilitiesHandler FROM PROPATH.
+USING Progress.Json.ObjectModel.ObjectModelParser FROM PROPATH.
+USING OpenEdge.DataAdmin.IIndex FROM PROPATH.
+
+CLASS admin.usersHandler FINAL:
+    DEFINE VARIABLE oJsonData    AS JsonObject        NO-UNDO.
+    DEFINE VARIABLE oJsonArray   AS JsonArray         NO-UNDO.
+    DEFINE VARIABLE oParser      AS ObjectModelParser NO-UNDO.
+    
+    DEFINE VARIABLE cuser_name   AS CHARACTER         NO-UNDO.
+    DEFINE VARIABLE ccompany     AS CHARACTER         NO-UNDO.
+    DEFINE VARIABLE lcJsonString AS LONGCHAR          NO-UNDO.
+        
+    DEFINE VARIABLE iMaxRecords  AS INTEGER           NO-UNDO INIT 5.
+    DEFINE VARIABLE iStartPage   AS INTEGER           NO-UNDO.
+    DEFINE VARIABLE iStartRecord AS INTEGER           NO-UNDO.
+    DEFINE VARIABLE iPageCounter AS INTEGER           NO-UNDO.
+    
+    DEFINE VARIABLE httusers     AS HANDLE            NO-UNDO.
+    DEFINE VARIABLE ttusers      AS HANDLE            NO-UNDO.
+    
+    DEFINE VARIABLE hQuery       AS HANDLE            NO-UNDO.
+    DEFINE VARIABLE hBuffer      AS HANDLE            NO-UNDO.
+    
+    DEFINE BUFFER busers FOR users.
+         
+    DEFINE VARIABLE outilitiesHandler AS utilitiesHandler NO-UNDO.
+    
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD PUBLIC LOGICAL createData(
+        INPUT  oJsonIdent  AS JsonObject,
+        INPUT  oJsonRecord AS jsonObject,
+        OUTPUT oJsonReturn AS JsonObject  
+        ):
+            
+        DEFINE VARIABLE oJsonMessage  AS JsonObject NO-UNDO.
+        DEFINE VARIABLE oJsonPosition AS JsonObject NO-UNDO.
+
+        DEFINE VARIABLE lRetVal       AS LOGICAL    NO-UNDO.
+        DEFINE VARIABLE ii            AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE i1            AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE iIndex        AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE cWordIndex    AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cSortField    AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cDirection    AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cWhere        AS CHARACTER  NO-UNDO.
+
+        outilitiesHandler = NEW utilitiesHandler().
+        
+        CREATE TEMP-TABLE ttusers.
+        ttusers:ADD-FIELDS-FROM ('users', 'wordindex'). /*  except Field wordindex  */
+        ttusers:TEMP-TABLE-PREPARE ('record').
+        httusers = ttusers:DEFAULT-BUFFER-HANDLE.
+
+        DO ii = 1 TO httusers:NUM-FIELDS:
+            httusers:BUFFER-FIELD(ii):SERIALIZE-NAME = 'users_' + httusers:BUFFER-FIELD(ii):NAME NO-ERROR.
+        END.
+
+        httusers:READ-JSON('JsonObject', oJsonRecord) NO-ERROR.
+        httusers:FIND-FIRST('', NO-LOCK).
+        hBuffer = BUFFER busers:HANDLE.
+        cuser_name = httusers:BUFFER-FIELD('user_name'):BUFFER-VALUE.
+
+        lRetVal = FALSE.
+                
+        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
+            FIND FIRST users NO-LOCK 
+                WHERE users.user_name = cuser_name NO-ERROR.
+            IF AVAILABLE users THEN LEAVE.
+
+            CREATE  busers.
+            hBuffer = BUFFER busers:HANDLE.        
+            DO ii = 1 TO httusers:NUM-FIELDS:
+                // IF httusers:BUFFER-FIELD(ii):BUFFER-VALUE = hBuffer:BUFFER-FIELD(ii):BUFFER-VALUE THEN NEXT.
+                hBuffer:BUFFER-FIELD(ii):BUFFER-VALUE = httusers:BUFFER-FIELD(ii):BUFFER-VALUE. 
+            END.
+            busers.created_at = NOW.
+            cWordIndex = outilitiesHandler:createWordindex(
+                INPUT hBuffer
+                ).
+            busers.wordindex = cWordIndex.
+            
+            oJsonReturn = NEW JsonObject().
+            oJsonData   = NEW JsonObject().
+            oJsonArray  = NEW JsonArray ().
+            httusers:BUFFER-COPY(hBuffer).
+            httusers:WRITE-JSON('JsonObject', oJsonData).
+    
+            oJsonArray = oJsonData:GetJsonArray('record').
+            oJsonData  = oJsonArray:GetJsonObject(1). 
+            oJsonReturn:ADD('record', oJsonData).
+            
+            RELEASE busers.
+            
+            FIND userdata
+                WHERE userdata.user_name   = oJsonIdent:GetCharacter('user_name')
+                AND   userdata.company     = oJsonIdent:GetCharacter('company')
+                AND   userdata.branch      = '0000'
+                AND   userdata.record_type = 'sortField'
+                AND   userdata.section     = 'users' 
+                AND   userdata.key_type    = '' NO-ERROR.
+            IF AVAILABLE userdata THEN 
+            DO: 
+                ASSIGN 
+                    cSortField = userdata.cfield_1
+                    cDirection = userdata.cfield_2.
+            END.
+            IF cDirection BEGINS 'asc' THEN cDirection = ''.
+            
+            hBuffer = BUFFER users:HANDLE.
+            CREATE QUERY hQuery.
+            hQuery:SET-BUFFERS (hBuffer).
+            cWhere = 'FOR EACH users NO-LOCK '.
+            IF cSortField <> '' THEN cWhere = cWhere + ' BY ' + cSortField + ' ' + cDirection.
+            hQuery:QUERY-PREPARE(cWhere).
+            hQuery:QUERY-OPEN().
+            hQuery:GET-FIRST().
+            
+            ii = 0.
+            i1 = 0.  
+            DO WHILE NOT hQuery:QUERY-OFF-END:
+                ii = ii + 1.
+                IF hBuffer:BUFFER-FIELD('user_name'):BUFFER-VALUE = cuser_name THEN i1 = ii.
+                hQuery:GET-NEXT ().
+            END.
+            hQuery:QUERY-CLOSE ().
+        
+            iPageCounter = i1 / iMaxRecords.
+            IF (iPageCounter * iMaxRecords) < i1 THEN iPageCounter = iPageCounter + 1.
+
+            iIndex = i1 MOD iMaxRecords.
+            IF iIndex = 0 THEN iIndex = iMaxRecords.
+                          
+            oJsonPosition = NEW JsonObject().
+            oJsonPosition:ADD('page', iPageCounter).
+            oJsonPosition:ADD('index', iIndex - 1).     /* -1 weil in Java beginnt Index bei 0  */
+            oJsonPosition:ADD('totalRecords', ii).
+            
+            oJsonReturn:ADD('position', oJsonPosition).
+
+            lRetVal = TRUE.
+            LEAVE.
+        END.
+        
+        IF NOT lRetVal THEN 
+        DO:
+            oJsonMessage = NEW JsonObject().
+            oJsonMessage:ADD('success', FALSE).
+            oJsonMessage:WRITE(lcJsonString, FALSE).
+        END.
+        
+        RETURN lRetVal.
+
+        CATCH e AS Progress.Lang.Error:
+
+        END CATCH.
+
+        FINALLY:
+
+        END FINALLY.
+
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD PUBLIC LOGICAL deleteData(
+        INPUT  oJsonIdent  AS JsonObject,
+        INPUT  oJsonRecord AS jsonObject,
+        OUTPUT oJsonReturn AS JsonObject  
+        ):
+
+        DEFINE VARIABLE lRetVal       AS LOGICAL    NO-UNDO.
+        DEFINE VARIABLE ii            AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE i1            AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE iIndex        AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE cSortField    AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cDirection    AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cWhere        AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE rUsers        AS RECID      NO-UNDO.
+        
+        DEFINE VARIABLE oJsonPosition AS JsonObject NO-UNDO.
+
+        outilitiesHandler = NEW utilitiesHandler().
+        
+        CREATE TEMP-TABLE ttusers.
+        ttusers:ADD-FIELDS-FROM ('users', 'wordindex'). /*  except Field wordindex  */
+        ttusers:TEMP-TABLE-PREPARE ('record').
+        httusers = ttusers:DEFAULT-BUFFER-HANDLE.
+         
+        DO ii = 1 TO httusers:NUM-FIELDS:
+            httusers:BUFFER-FIELD(ii):SERIALIZE-NAME = 'users_' + httusers:BUFFER-FIELD(ii):NAME NO-ERROR.
+        END.
+
+        httusers:READ-JSON('JsonObject', oJsonRecord) NO-ERROR.
+        httusers:FIND-FIRST('', NO-LOCK).
+        hBuffer = BUFFER busers:HANDLE.
+        cuser_name = httusers:BUFFER-FIELD('user_name'):BUFFER-VALUE.
+        
+        lRetVal = FALSE.
+        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
+            FIND FIRST users NO-LOCK 
+                WHERE users.user_name = cuser_name NO-ERROR.
+            IF NOT AVAILABLE users THEN LEAVE.
+            rUsers = RECID(users).
+
+            FIND userdata
+                WHERE userdata.user_name   = oJsonIdent:GetCharacter('user_name')
+                AND   userdata.company     = oJsonIdent:GetCharacter('company')
+                AND   userdata.branch      = '0000'
+                AND   userdata.record_type = 'sortField'
+                AND   userdata.section     = 'users' 
+                AND   userdata.key_type    = '' NO-ERROR.
+            IF AVAILABLE userdata THEN 
+            DO: 
+                ASSIGN 
+                    cSortField = userdata.cfield_1
+                    cDirection = userdata.cfield_2.
+            END.
+            IF cDirection BEGINS 'asc' THEN cDirection = ''.
+            
+            hBuffer = BUFFER users:HANDLE.
+            CREATE QUERY hQuery.
+            hQuery:SET-BUFFERS (hBuffer).
+            cWhere = 'FOR EACH users NO-LOCK '.
+            IF cSortField <> '' THEN cWhere = cWhere + ' BY ' + cSortField + ' ' + cDirection.
+            hQuery:QUERY-PREPARE(cWhere).
+            hQuery:QUERY-OPEN().
+            hQuery:GET-FIRST().
+            
+            ii = 0.
+            i1 = 0.  
+            DO WHILE NOT hQuery:QUERY-OFF-END:
+                ii = ii + 1.
+                IF hBuffer:BUFFER-FIELD('user_name'):BUFFER-VALUE = cuser_name THEN i1 = ii.
+                hQuery:GET-NEXT ().
+            END.
+            hQuery:QUERY-CLOSE ().
+        
+            iPageCounter = i1 / iMaxRecords.
+            IF (iPageCounter * iMaxRecords) < i1 THEN iPageCounter = iPageCounter + 1.
+
+            iIndex = i1 MOD iMaxRecords.
+            IF iIndex = 0 THEN iIndex = iMaxRecords.
+            
+            FIND users WHERE RECID(users) = rUsers.
+            DELETE users.
+            RELEASE users.
+                          
+            lRetVal = TRUE.
+            oJsonReturn   = NEW JsonObject().
+            oJsonReturn:ADD('success', lRetVal).
+            
+            oJsonPosition = NEW JsonObject().
+            oJsonPosition:ADD('page', iPageCounter).
+            oJsonPosition:ADD('index', iIndex - 1).     /* -1 weil in Java beginnt Index bei 0  */
+            oJsonPosition:ADD('totalRecords', ii).
+            
+            oJsonReturn:ADD('position', oJsonPosition).
+
+            LEAVE.
+        END.
+        
+        RETURN lRetVal.
+
+        CATCH e AS Progress.Lang.Error:
+
+        END CATCH.
+
+        FINALLY:
+
+        END FINALLY.
+
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD PUBLIC LOGICAL getChanges(
+        INPUT  oJsonIdent  AS JsonObject,
+        OUTPUT oJsonResult AS JsonObject
+        ):
+            
+        DEFINE VARIABLE lRetVal           AS LOGICAL    NO-UNDO.
+        
+        DEFINE VARIABLE cFunction         AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cField            AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cAction           AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cValue            AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cKeyFields        AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cKeyValues        AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE lcJsonString      AS LONGCHAR   NO-UNDO.
+        DEFINE VARIABLE cWhere            AS CHARACTER  NO-UNDO.
+        DEFINE VARIABLE cString           AS CHARACTER  NO-UNDO.
+        
+        DEFINE VARIABLE i1                AS INTEGER    NO-UNDO.
+        DEFINE VARIABLE i2                AS INTEGER    NO-UNDO.
+        
+        DEFINE VARIABLE oJsonfieldUpdates AS JsonObject NO-UNDO.
+        
+        outilitiesHandler = NEW utilitiesHandler().
+        
+        cField  = oJsonIdent:GetCharacter('field').
+        cAction = oJsonIdent:GetCharacter('action').
+        cValue  = REPLACE(oJsonIdent:GetCharacter('value'), '+', ' ').
+
+        oJsonResult       = NEW JsonObject().
+        oJsonFieldUpdates = NEW JsonObject().
+
+        lRetVal = outilitiesHandler:getKeyFields(
+            INPUT  oJsonIdent   ,
+            OUTPUT cKeyFields   ,
+            OUTPUT cKeyValues
+            ).
+        cWhere     = ''.
+        lRetVal    = FALSE.
+        DO WHILE TRUE:
+            DO i1 = 1 TO NUM-ENTRIES(cKeyFields, ';'):
+                cWhere = cWhere
+                    + (IF cWhere = '' THEN 'WHERE ' ELSE 'AND ' )
+                    + SUBSTITUTE('busers.&1 = &2 ',
+                    REPLACE(ENTRY(i1, cKeyFields, ';'), 'users_', ''),
+                    ENTRY(i1, cKeyValues, CHR(01))).
+            END.
+MESSAGE cWhere.
+            hBuffer = BUFFER busers:HANDLE.
+            lRetVal = hBuffer:FIND-UNIQUE(cWhere, NO-LOCK) NO-ERROR.
+            IF lRetVal THEN 
+            DO:
+                CASE cField:
+                    WHEN 'users_firstname' THEN 
+                        DO:
+                            IF hBuffer::display_Name = '' THEN 
+                            DO:
+                                cString = cValue + ' ' + hBuffer::lastname.
+                                oJsonfieldUpdates:ADD('users_display_name', cString).
+                            END.
+                            IF hBuffer::initials = '' THEN 
+                            DO:
+                                cString = TRIM(SUBSTRING(cValue,01,02)) + TRIM(SUBSTRING(hBuffer::lastname,01,02)).
+                                oJsonfieldUpdates:ADD('users_initials', cString).
+                            END.
+                        END.
+                END CASE.
+                oJsonResult:ADD('fieldUpdates', oJsonfieldUpdates).
+            END.
+        
+            lRetVal = TRUE.
+            LEAVE.
+        END.
+
+        IF NOT lRetVal THEN 
+        DO:
+            oJsonResult = NEW JsonObject().
+            oJsonResult:ADD('success', FALSE).
+            oJsonResult:ADD('message', 'Fehler beim change').
+        END.
+                
+        RETURN lRetVal.
+
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD PUBLIC LOGICAL getData(
+        INPUT  oJsonIdent  AS JsonObject,
+        OUTPUT oJsonReturn AS JsonObject  
+        ):
+        
+        DEFINE VARIABLE ii           AS INTEGER   NO-UNDO.
+        DEFINE VARIABLE i1           AS INTEGER   NO-UNDO.
+        DEFINE VARIABLE lRetVal      AS LOGICAL   NO-UNDO.
+        DEFINE VARIABLE cSortField   AS CHARACTER NO-UNDO INIT ''.
+        DEFINE VARIABLE cSearchChars AS CHARACTER NO-UNDO INIT ''.
+        DEFINE VARIABLE cValue       AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE lWordIndex   AS LOGICAL   NO-UNDO INIT FALSE.
+        DEFINE VARIABLE cDirection   AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE cFilters     AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE cFilter      AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE cFields      AS CHARACTER NO-UNDO EXTENT.
+        DEFINE VARIABLE cField       AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE cDBField     AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE cWhere       AS CHARACTER NO-UNDO.
+        DEFINE VARIABLE cType        AS CHARACTER NO-UNDO.
+        
+        
+        DEFINE VARIABLE oRecords     AS JsonArray NO-UNDO.
+        
+        CREATE BUFFER hBuffer FOR TABLE 'users'.
+        
+        cuser_name = oJsonIdent:GetCharacter('user_name').
+        ccompany   = oJsonIdent:GetCharacter('company').
+        cSortField = ''.
+        cDirection = ''.
+        
+        iStartPage = 1.
+        IF oJsonIdent:HAS('page') THEN iStartPage = INTEGER(oJsonIdent:GetCharacter('page')) NO-ERROR.
+        iStartRecord = ((iStartPage - 1) * iMaxRecords) + 1. 
+        
+        IF oJsonIdent:HAS('search') THEN 
+        DO:
+            cSearchChars = oJsonIdent:GetCharacter('search').
+            lWordIndex   = TRUE.
+            /*            iMaxRecords  = 100.*/
+            /*            cSortField   = ''. */
+            iStartRecord = 1.
+        END.
+        
+        IF lWordIndex THEN
+        DO:
+            DO ii = 1 TO NUM-ENTRIES(cSearchChars):
+                cValue = ENTRY(ii, cSearchChars, ' ').
+                cWhere = cWhere + (IF cWhere = '' THEN 'WHERE ' ELSE 'AND ')
+                    + 'LOOKUP(' + QUOTER(cValue) + ', users.wordindex, " ") > 0 '. 
+            END.
+        END.
+        ELSE 
+        DO: 
+            IF oJsonIdent:HAS('sortField') THEN 
+            DO:
+                cSortField = REPLACE(oJsonIdent:GetCharacter('sortField'), 'users_', '').
+                cDirection = oJsonIdent:GetCharacter('sortDirection').
+            END.
+              
+            REPEAT TRANSACTION ON ERROR UNDO, LEAVE:  
+                FIND userdata
+                    WHERE userdata.user_name   = cuser_name
+                    AND   userdata.company     = ccompany
+                    AND   userdata.branch      = '0000'
+                    AND   userdata.record_type = 'sortField'
+                    AND   userdata.section     = 'users' 
+                    AND   userdata.key_type    = '' NO-ERROR.
+              
+                IF NOT AVAILABLE userdata THEN 
+                DO:
+                    CREATE  userdata.
+                    ASSIGN 
+                        userdata.user_name   = cuser_name
+                        userdata.company     = ccompany
+                        userdata.branch      = '0000'
+                        userdata.record_type = 'sortField'
+                        userdata.section     = 'users' 
+                        userdata.key_type    = '' NO-ERROR.
+                END.
+                ASSIGN  
+                    userdata.cfield_1 = cSortfield
+                    userdata.cfield_2 = cDirection.
+                RELEASE userdata.
+                LEAVE.
+            END.
+        
+            cFields = oJsonIdent:GetNames().
+            cWhere  = ''.
+            DO i1 = 1 TO EXTENT(cFields):
+                cField = cFields[i1].
+                IF NOT cField BEGINS 'filter_' THEN NEXT. 
+                cFilter = oJsonIdent:GetCharacter(cField).
+                cField  = REPLACE(cField, 'filter_users_', '').
+                cType   = hBuffer:BUFFER-FIELD(cField):DATA-TYPE.
+                CASE cType:
+                    WHEN 'character' THEN 
+                        cFilter = QUOTER(cFilter).
+                    WHEN 'logical'   THEN 
+                        cFilter = STRING(cFilter,'yes/no').
+                    WHEN 'date'      THEN 
+                        cFilter = STRING(DATE(cFilter),'99.99.9999').
+                END CASE.
+                cDBField = SUBSTITUTE('users.&1', cField).
+                cWhere = cWhere
+                    + (IF cWhere = '' THEN 'WHERE ' ELSE 'AND ')
+                    + 'INDEX(' + cDBField + ', ' + cFilter + ') > 0 '.
+            END.
+        END.
+
+        IF NOT cDirection BEGINS 'des' THEN cDirection = ''.
+        IF cSortField <> '' THEN cWhere = cWhere + 'BY ' + cSortField + ' ' + cDirection.
+         
+        CREATE TEMP-TABLE ttusers.
+        ttusers:ADD-FIELDS-FROM ('users', 'wordindex').
+        IF cSortField <> '' THEN 
+        DO:
+            ttusers:ADD-NEW-INDEX ('ttuser-k1', FALSE, TRUE).     /*  UNIQUE, PRIMARY */
+            IF cDirection BEGINS 'des' THEN ttusers:ADD-INDEX-FIELD ('ttUser-k1', cSortField, 'desc').
+            ELSE                            ttusers:ADD-INDEX-FIELD ('ttUser-k1', cSortField).
+        END.
+        ttusers:TEMP-TABLE-PREPARE ('records').
+        httusers = ttusers:DEFAULT-BUFFER-HANDLE.
+         
+        DO ii = 1 TO httusers:NUM-FIELDS:
+            httusers:BUFFER-FIELD(ii):SERIALIZE-NAME = 'users_' + httusers:BUFFER-FIELD(ii):NAME NO-ERROR.
+        END.
+
+        ii = 0.
+        i1 = 0.
+        ttusers:EMPTY-TEMP-TABLE ().
+        CREATE QUERY hQuery.
+        hQuery:SET-BUFFERS (hBuffer) NO-ERROR.
+        hQuery:QUERY-PREPARE (SUBSTITUTE('FOR EACH users NO-LOCK &1 ', cWhere)) NO-ERROR.
+        hQuery:QUERY-OPEN ().
+        hQuery:GET-FIRST ().
+
+        DO WHILE NOT hQuery:QUERY-OFF-END:
+            ii = ii + 1.
+            IF ii < iStartRecord THEN 
+            DO:
+                hQuery:GET-NEXT ().
+                NEXT.
+            END.
+            i1 = i1 + 1.
+            IF i1 <= iMaxRecords THEN 
+            DO:
+                httusers:BUFFER-CREATE().
+                httusers:BUFFER-COPY(hBuffer).
+            END.
+            hQuery:GET-NEXT ().
+        END.
+        hQuery:QUERY-CLOSE ().
+        DELETE OBJECT hBuffer NO-ERROR.
+        
+        iPageCounter = ii / iMaxRecords.
+        IF (iPageCounter * iMaxRecords) < ii THEN iPageCounter = iPageCounter + 1.  
+        oRecords = NEW JsonArray().
+        httusers:WRITE-JSON('JsonArray', oRecords).
+        
+        oJsonReturn = NEW JsonObject().
+        oJsonReturn:ADD('records'   , oRecords).
+        oJsonReturn:ADD('maxRecords', ii).
+        oJsonReturn:ADD('pageCount' , iPageCounter).
+
+        lRetVal = TRUE.        
+        RETURN lRetVal.
+
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD PUBLIC LOGICAL updateData(
+        INPUT  oJsonIdent  AS JsonObject,
+        INPUT  oJsonRecord AS jsonObject,
+        OUTPUT oJsonReturn AS JsonObject  
+        ):
+
+        DEFINE VARIABLE lRetVal    AS LOGICAL   NO-UNDO.
+        DEFINE VARIABLE ii         AS INTEGER   NO-UNDO.
+        DEFINE VARIABLE cWordIndex AS CHARACTER NO-UNDO.
+
+        outilitiesHandler = NEW utilitiesHandler().
+        
+        CREATE TEMP-TABLE ttusers.
+        ttusers:ADD-FIELDS-FROM ('users', 'wordindex'). /*  except Field wordindex  */
+        ttusers:TEMP-TABLE-PREPARE ('record').
+        httusers = ttusers:DEFAULT-BUFFER-HANDLE.
+         
+        DO ii = 1 TO httusers:NUM-FIELDS:
+            httusers:BUFFER-FIELD(ii):SERIALIZE-NAME = 'users_' + httusers:BUFFER-FIELD(ii):NAME NO-ERROR.
+        END.
+
+        httusers:READ-JSON('JsonObject', oJsonRecord) NO-ERROR.
+        httusers:FIND-FIRST('', NO-LOCK).
+        hBuffer = BUFFER busers:HANDLE.
+        cuser_name = httusers:BUFFER-FIELD('user_name'):BUFFER-VALUE.
+        
+        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
+            FIND busers
+                WHERE busers.user_name = cuser_name NO-ERROR.
+            DO ii = 1 TO httusers:NUM-FIELDS:
+                IF httusers:BUFFER-FIELD(ii):BUFFER-VALUE = hBuffer:BUFFER-FIELD(ii):BUFFER-VALUE THEN NEXT.
+                hBuffer:BUFFER-FIELD(ii):BUFFER-VALUE = httusers:BUFFER-FIELD(ii):BUFFER-VALUE. 
+            END.
+            busers.updated_at = NOW.
+            cWordIndex = outilitiesHandler:createWordindex(
+                INPUT hBuffer
+                ).
+            busers.wordindex = cWordIndex.
+            
+            oJsonReturn = NEW JsonObject().
+            oJsonData   = NEW JsonObject().
+            oJsonArray  = NEW JsonArray ().
+            httusers:BUFFER-COPY(hBuffer).
+            httusers:WRITE-JSON('JsonObject', oJsonData).
+    
+            oJsonArray = oJsonData:GetJsonArray('record').
+            oJsonData  = oJsonArray:GetJsonObject(1). 
+            oJsonReturn:ADD('record', oJsonData).
+            
+            RELEASE busers.
+            lRetVal = TRUE.
+            LEAVE.
+        END.
+        
+        RETURN lRetVal.
+
+        CATCH e AS Progress.Lang.Error:
+
+        END CATCH.
+
+        FINALLY:
+
+        END FINALLY.
+
+    END METHOD.
+
+    DESTRUCTOR PUBLIC usersHandler ( ):
+
+    END DESTRUCTOR.
+
+END CLASS.

+ 393 - 0
admin/usersImpl.cls

@@ -0,0 +1,393 @@
+ 
+/*------------------------------------------------------------------------
+   File        : adresse_dict
+   Purpose     : 
+   Syntax      : 
+   Description : 
+   Author(s)   : walter.riechsteiner
+   Created     : Thu Jun 26 13:56:20 CEST 2025
+   Notes       : 
+ ----------------------------------------------------------------------*/
+ 
+BLOCK-LEVEL ON ERROR UNDO, THROW.
+
+USING OpenEdge.Core.String FROM PROPATH.
+USING OpenEdge.Net.HTTP.IHttpResponse FROM PROPATH.
+USING OpenEdge.Net.HTTP.StatusCodeEnum FROM PROPATH.
+USING OpenEdge.Web.IWebRequest FROM PROPATH.
+USING OpenEdge.Web.WebHandler FROM PROPATH.
+USING OpenEdge.Web.WebResponseWriter FROM PROPATH.
+USING Progress.Json.ObjectModel.JsonObject FROM PROPATH.
+USING Progress.Json.ObjectModel.JsonArray FROM PROPATH.
+USING Progress.Json.ObjectModel.ObjectModelParser FROM PROPATH.
+USING src.ch.adprime.gemis.WebHandlerUtilities FROM PROPATH.
+USING utilities.utilitiesHandler FROM PROPATH.
+
+CLASS admin.usersImpl INHERITS WebHandler: 
+
+    DEFINE VARIABLE outilitiesHandler AS utilitiesHandler NO-UNDO.
+    
+    DEFINE TEMP-TABLE tusers
+        SERIALIZE-NAME 'users'
+        FIELD id          AS INT64     SERIALIZE-NAME 'id'
+        FIELD username    AS CHARACTER SERIALIZE-NAME 'username'
+        FIELD password    AS CHARACTER SERIALIZE-NAME 'password'
+        FIELD firstname   AS CHARACTER SERIALIZE-NAME 'firstname'
+        FIELD lastname    AS CHARACTER SERIALIZE-NAME 'lastname'
+        FIELD email       AS CHARACTER SERIALIZE-NAME 'email'
+        FIELD displayname AS CHARACTER SERIALIZE-NAME 'displayname'
+        FIELD role        AS CHARACTER SERIALIZE-NAME 'role'
+        FIELD language_id AS INTEGER   SERIALIZE-NAME 'language_id'
+        FIELD active      AS LOGICAL   SERIALIZE-NAME 'active'
+        FIELD created_at  AS CHARACTER SERIALIZE-NAME 'created_at'
+        FIELD updated_at  AS CHARACTER SERIALIZE-NAME 'updated_at'
+        FIELD iStatus     AS INTEGER   SERIALIZE-HIDDEN
+        .
+    DEFINE VARIABLE htusers AS HANDLE NO-UNDO.
+
+    DEFINE TEMP-TABLE tusersUpdate
+        SERIALIZE-NAME 'users'
+        FIELD id          AS INT64     SERIALIZE-NAME 'id'
+        FIELD username    AS CHARACTER SERIALIZE-NAME 'username'
+        FIELD password    AS CHARACTER SERIALIZE-NAME 'password'
+        FIELD firstname   AS CHARACTER SERIALIZE-NAME 'firstname'
+        FIELD lastname    AS CHARACTER SERIALIZE-NAME 'lastname'
+        FIELD email       AS CHARACTER SERIALIZE-NAME 'email'
+        FIELD displayname AS CHARACTER SERIALIZE-NAME 'displayname'
+        FIELD role        AS CHARACTER SERIALIZE-NAME 'role'
+        FIELD language_id AS INTEGER   SERIALIZE-NAME 'language_id'
+        FIELD active      AS LOGICAL   SERIALIZE-NAME 'active'
+        FIELD created_at  AS CHARACTER SERIALIZE-NAME 'created_at'
+        FIELD updated_at  AS CHARACTER SERIALIZE-NAME 'updated_at'
+        .
+    DEFINE VARIABLE htusersUpdate AS HANDLE NO-UNDO.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleGet (INPUT poRequest AS IWebRequest ):
+        DEFINE VARIABLE oResponse       AS IHttpResponse                NO-UNDO.         
+        DEFINE VARIABLE oWriter         AS WebResponseWriter            NO-UNDO.
+        DEFINE VARIABLE oBody           AS String                       NO-UNDO.
+        DEFINE VARIABLE oJsonResponse   AS JsonObject                   NO-UNDO.
+        DEFINE VARIABLE cDefautlCharSet AS CHARACTER                    NO-UNDO INIT 'UTF-8'.
+        DEFINE VARIABLE cCorralationID  AS CHARACTER                    NO-UNDO.
+        DEFINE VARIABLE cContent-Type   AS CHARACTER                    NO-UNDO.
+        DEFINE VARIABLE oParser         AS ObjectModelParser            NO-UNDO.           
+        DEFINE VARIABLE oHeader         AS OpenEdge.Net.HTTP.HttpHeader NO-UNDO.
+        DEFINE VARIABLE lcJsonString    AS LONGCHAR                     NO-UNDO.
+
+        DEFINE VARIABLE cMandant        AS CHARACTER                    NO-UNDO.
+        DEFINE VARIABLE cBenutzer       AS CHARACTER                    NO-UNDO.
+        DEFINE VARIABLE cAnzeigeName    AS CHARACTER                    NO-UNDO.
+        DEFINE VARIABLE iSprcd          AS INTEGER                      NO-UNDO.
+        DEFINE VARIABLE cSessionToken   AS CHARACTER                    NO-UNDO.
+        DEFINE VARIABLE lRetVal         AS LOGICAL                      NO-UNDO INIT FALSE.        
+
+        DEFINE VARIABLE cFunction       AS CHARACTER                    NO-UNDO.        
+        DEFINE VARIABLE cusername       AS CHARACTER                    NO-UNDO.
+        DEFINE VARIABLE language_id     AS INTEGER                      NO-UNDO.
+        DEFINE VARIABLE oJsonUsers      AS JsonObject                   NO-UNDO.
+        DEFINE VARIABLE lOk             AS LOGICAL                      NO-UNDO.
+        DEFINE VARIABLE ii              AS INTEGER                      NO-UNDO.
+        DEFINE VARIABLE dDateTime       AS DATETIME                     NO-UNDO.
+        DEFINE VARIABLE cDateTime       AS CHARACTER                    NO-UNDO.
+        
+        oHeader      = poRequest:GetHeader('X-MANDANT-ID').
+        cMandant     = oHeader:VALUE.
+        
+        oHeader      = poRequest:GetHeader('X-USERNAME').
+        cBenutzer    = oHeader:VALUE.
+        
+        oHeader      = poRequest:GetHeader('X-USERDISPLAY').
+        cAnzeigeName = oHeader:VALUE.
+        
+        oHeader = poRequest:GetHeader('X-LANGUAGE-ID').
+        iSprcd  = INTEGER(oHeader:VALUE).
+        
+        oHeader = poRequest:GetHeader('X-SESSION-TOKEN').
+        cSessionToken = oHeader:VALUE.
+        
+        outilitiesHandler = NEW utilitiesHandler().
+        
+        DEFINE BUFFER busers FOR users.
+
+        cFunction = poRequest:URI:GetQueryValue("function") NO-ERROR.         
+        cusername = poRequest:URI:GetQueryValue("username") NO-ERROR.         
+        
+        MESSAGE 'Function = ' cFunction 'username = ' cusername.
+
+        EMPTY TEMP-TABLE tusers.
+        EMPTY TEMP-TABLE tusersupdate.
+         
+        DO WHILE cFunction = 'init':
+            FOR EACH users NO-LOCK:
+                CREATE  tusers.
+                BUFFER-COPY users
+                    EXCEPT  users.created_at users.updated_at
+                    TO      tusers
+                    ASSIGN
+                    tusers.created_at = outilitiesHandler:getCharDateTime( users.created_at )
+                    tusers.updated_at = outilitiesHandler:getCharDateTime( users.updated_at ).
+            END.
+            lRetVal = TRUE.
+            LEAVE.
+        END.
+                
+/*        EMPTY TEMP-TABLE tusers.                                                                                                          */
+/*        FIND FIRST users NO-LOCK                                                                                                          */
+/*            WHERE users.username   = cusername                                                                                            */
+/*            AND   users.language_id    = iSprcd NO-ERROR.                                                                                 */
+/*        IF NOT AVAILABLE users THEN                                                                                                       */
+/*        DO:                                                                                                                               */
+/*            FIND FIRST users NO-LOCK                                                                                                      */
+/*                WHERE users.mandant  = cMandant                                                                                           */
+/*                AND   users.username = 'admin'                                                                                            */
+/*                AND   users.language_id    = iSprcd NO-ERROR.                                                                             */
+/*            IF AVAILABLE users THEN                                                                                                       */
+/*            DO:                                                                                                                           */
+/*                FOR EACH  users NO-LOCK                                                                                                   */
+/*                    WHERE users.mandant  = cMandant                                                                                       */
+/*                    AND   users.username = 'admin'                                                                                        */
+/*                    AND   users.language_id    = iSprcd:                                                                                  */
+/*                    CREATE busers.                                                                                                        */
+/*                    BUFFER-COPY users                                                                                                     */
+/*                        EXCEPT      users                                                                                                 */
+/*                        TO          busers                                                                                                */
+/*                        ASSIGN                                                                                                            */
+/*                        busers.username = cusername                                                                                       */
+/*                        busers.erstellt_am = NOW                                                                                          */
+/*                        .                                                                                                                 */
+/*                END.                                                                                                                      */
+/*            END.                                                                                                                          */
+/*        END.                                                                                                                              */
+/*        FOR EACH users NO-LOCK                                                                                                            */
+/*            WHERE users.mandant  = cMandant                                                                                               */
+/*            AND   users.username = cusername                                                                                              */
+/*            AND   users.language_id    = iSprcd:                                                                                          */
+/*                                                                                                                                          */
+/*            CREATE  tusers.                                                                                                               */
+/*            BUFFER-COPY users                                                                                                             */
+/*                EXCEPT erstellt_am mutiert_am                                                                                             */
+/*                TO     tusers.                                                                                                            */
+/*            ASSIGN                                                                                                                        */
+/*                tusers.cId = SUBSTITUTE('&1&2&3', STRING(users.stufe1,'9999'), STRING(users.stufe2,'9999'), STRING(users.stufe3,'9999') ).*/
+/*                                                                                                                                          */
+/*            dDateTime = (IF users.erstellt_am <> ? THEN users.erstellt_am ELSE NOW).                                                      */
+/*            cDateTime = STRING(dDateTime,'99-99-9999THH:MM:SS').                                                                          */
+/*            tusers.erstellt_am = STRING(YEAR(dDateTime),'9999')                                                                           */
+/*                + '-'                                                                                                                     */
+/*                + STRING(MONTH(dDateTime),'99')                                                                                           */
+/*                + '-'                                                                                                                     */
+/*                + STRING(DAY(dDateTime),'99')                                                                                             */
+/*                + SUBSTRING(cDateTime,11).                                                                                                */
+/*            dDateTime = (IF users.mutiert_am <> ? THEN users.mutiert_am ELSE NOW).                                                        */
+/*            cDateTime = STRING(dDateTime,'99-99-9999THH:MM:SS').                                                                          */
+/*            tusers.mutiert_am = STRING(YEAR(dDateTime),'9999')                                                                            */
+/*                + '-'                                                                                                                     */
+/*                + STRING(MONTH(dDateTime),'99')                                                                                           */
+/*                + '-'                                                                                                                     */
+/*                + STRING(DAY(dDateTime),'99')                                                                                             */
+/*                + SUBSTRING(cDateTime,11).                                                                                                */
+/*        END.                                                                                                                              */
+        
+        htusers = TEMP-TABLE tusers:DEFAULT-BUFFER-HANDLE.
+                 
+        cContent-Type   = "application/json".
+        cDefautlCharSet = 'utf-8'. 
+        oJsonResponse   = NEW JsonObject().
+        oParser         = NEW ObjectModelParser().
+        
+        oJsonUsers = NEW JsonObject().
+        htusers:WRITE-JSON('JsonObject', oJsonUsers).
+        
+        oBody = NEW STRING(oJsonUsers:GetJsonText()).
+        WebHandlerUtilities:createHttpResponse(INPUT INTEGER(StatusCodeEnum:OK), INPUT oBody, INPUT cContent-Type, INPUT cDefautlCharSet, INPUT cCorralationID, OUTPUT oResponse).
+//        oResponse:SetHeader(HttpHeaderBuilder:Build(cHeaderCorralationID):Value(cCorralationID):Header).
+
+        
+        oWriter = NEW WebResponseWriter(oResponse).
+        oWriter:Open(). 
+        oWriter:Close(). 
+
+        RETURN 0.
+        
+        CATCH e AS Progress.Lang.Error:
+
+        END CATCH.
+
+        FINALLY:
+
+        END FINALLY.
+
+    END METHOD.
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleNotAllowedMethod(INPUT poRequest AS IWebRequest):
+        DEFINE VARIABLE result AS INTEGER NO-UNDO.
+        MESSAGE "HandleNotAllowedMethod called" VIEW-AS ALERT-BOX.
+        RETURN result.
+    END METHOD.
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleNotImplemented(INPUT poRequest AS IWebRequest):
+        DEFINE VARIABLE result AS INTEGER NO-UNDO.
+        MESSAGE "HandleNotImplemented called" VIEW-AS ALERT-BOX.
+        RETURN result.
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD OVERRIDE PROTECTED INTEGER HandlePost(INPUT poRequest AS IWebRequest):
+        
+        DEFINE VARIABLE oResponse     AS IHttpResponse     NO-UNDO.
+        DEFINE VARIABLE oWriter       AS WebResponseWriter NO-UNDO.
+        DEFINE VARIABLE oJsonData     AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonUsers    AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE oJsonMessage  AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonResponse AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oFelder       AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE oFeld         AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oParser       AS ObjectModelParser NO-UNDO.           
+        
+        DEFINE VARIABLE lRetVal       AS LOGICAL           NO-UNDO.
+        DEFINE VARIABLE lcJsonString  AS LONGCHAR          NO-UNDO.
+        DEFINE VARIABLE cJSON         AS LONGCHAR          NO-UNDO.
+        DEFINE VARIABLE i1            AS INTEGER           NO-UNDO.
+        
+        DEFINE VARIABLE cTabellen     AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cMandant      AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cusername     AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE iSprcd        AS INTEGER           NO-UNDO.
+        DEFINE VARIABLE cMaskenId     AS CHARACTER         NO-UNDO.
+        
+        lRetVal = WebHandlerUtilities:getJsonFromRequest(INPUT poRequest, OUTPUT oJsonData) NO-ERROR.
+
+        oJsonData:WRITE(lcJsonString, FALSE).
+        MESSAGE 'ganzer Eingangsstring = ' STRING(lcJsonString).
+            
+        cMandant  = oJsonData:GetCharacter('customer_id' ).
+        cusername = oJsonData:GetCharacter('user_id' ).
+        iSprcd    = INTEGER(oJsonData:GetCharacter('language_id')).
+
+        MESSAGE 'HANDLE POST ' cMandant '-' cusername '-' iSprcd.
+/*            
+        oParser       = NEW ObjectModelParser().
+        oJsonUsers  = NEW JsonArray().
+        oJsonResponse = NEW JsonObject().
+        lcJsonString  = oJsonData:GetJsonText('menuItems').
+        
+        oJsonUsers = CAST(oParser:Parse(lcJsonString), JsonArray) NO-ERROR.
+        oJsonResponse:ADD('menuItems', oJsonUsers).
+
+        htusersUpdate = TEMP-TABLE tusersUpdate:DEFAULT-BUFFER-HANDLE.
+        htusersUpdate:READ-JSON ('JsonObject', oJsonResponse, 'EMPTY').
+        
+        /*        oJsonResponse:WRITE(lcJsonString, FALSE).                   */
+        /*        htusersUpdate:READ-JSON ('longchar', lcJsonString, 'EMPTY').*/
+        
+        EMPTY TEMP-TABLE tusers.
+        FOR EACH users NO-LOCK
+            WHERE users.mandant  = cMandant
+            AND   users.username = cusername
+            AND   users.language_id    = iSprcd:
+                
+            CREATE tusers.
+            BUFFER-COPY users
+                EXCEPT  erstellt_am mutiert_am
+                TO tusers
+                ASSIGN 
+                tusers.istatus = 0.
+        END.
+        
+        FOR EACH tusersUpdate:
+            FIND tusers
+                WHERE tusers.mandant  = cMandant
+                AND   tusers.username = cusername
+                AND   tusers.language_id    = isprcd
+                AND   tusers.stufe1   = tusersUpdate.stufe1
+                AND   tusers.stufe2   = tusersUpdate.stufe2
+                AND   tusers.stufe3   = tusersUpdate.stufe3 NO-ERROR.
+                
+            IF NOT AVAILABLE tusers THEN 
+            DO:
+                CREATE tusers.
+                BUFFER-COPY tusersUpdate
+                    EXCEPT  Mandant users sprcd erstellt_am mutiert_am
+                    TO      tusers
+                    ASSIGN
+                    tusers.mandant     = cMandant
+                    tusers.username    = cusername
+                    tusers.language_id       = iSprcd
+                    tusers.iStatus     = 1.
+                NEXT.
+            END.
+            BUFFER-COPY tusersUpdate
+                EXCEPT  Mandant users sprcd erstellt_am mutiert_am
+                TO      tusers
+                ASSIGN 
+                tusers.istatus = 2.
+        END.
+        
+        REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
+            FOR EACH tusers:
+                IF tusers.istatus = 1 THEN 
+                DO:
+                    CREATE  users.
+                    BUFFER-COPY tusers
+                        EXCEPT  erstellt_am mutiert_am istatus
+                        TO      users
+                        ASSIGN  
+                        users.erstellt_am = NOW
+                        users.mutiert_am  = ?.
+                END.
+                FIND users OF tusers.
+                IF tusers.istatus = 0 THEN 
+                DO:
+                    DELETE users.
+                    NEXT.
+                END.
+                ASSIGN 
+                    users.menutext   = tusers.menutext
+                    users.menulink   = tusers.menulink
+                    users.mutiert_am = NOW. 
+            END.
+            RELEASE users.
+            LEAVE.
+        END.
+        
+        OUTPUT TO 'C:\TEMP\users.csv' NO-MAP NO-CONVERT.
+        FOR EACH users NO-LOCK:
+            EXPORT DELIMITER ';' users.
+        END.
+        OUTPUT CLOSE.
+        
+        oResponse             = NEW OpenEdge.Web.WebResponse().
+        oResponse:StatusCode  = INTEGER(StatusCodeEnum:OK).
+        oResponse:ContentType = "application/json;charset=utf-8".
+        oWriter               = NEW WebResponseWriter(oResponse).
+                    
+        oJsonMessage = NEW JsonObject().
+        oJsonMessage:ADD('success', TRUE).
+        oJsonMessage:WRITE(lcJsonString, TRUE).
+        MESSAGE 'Rückmeldung ' STRING(lcJsonString).
+                        
+        oWriter:Open().
+        oWriter:Write(lcJsonString).
+        oWriter:Close().
+*/            
+        CATCH e AS Progress.Lang.Error:
+            
+        END CATCH.
+            
+        FINALLY:
+        /*            DELETE OBJECT oJsonConfig. */
+        /*            DELETE OBJECT oJsonMessage.*/
+        END FINALLY.
+
+    END METHOD.
+
+END CLASS.

+ 9 - 9
adressen/gemis_startImpl.cls

@@ -160,7 +160,7 @@ CLASS gemis_startImpl INHERITS WebHandler:
                         WHERE bwebmenu.mandant  = webmenu.mandant
                         AND   bwebmenu.benutzer = ttInput.benutzer
                         AND   bwebmenu.sprcd    = webmenu.sprcd
-                        AND   bwebmenu.Position = webmenu.position NO-ERROR.
+                        AND   bwebmenu.stufe1   = webmenu.stufe1 NO-ERROR.
                     IF NOT AVAILABLE bwebmenu THEN CREATE bwebmenu.
                     BUFFER-COPY webmenu
                         EXCEPT  webmenu.benutzer
@@ -184,7 +184,7 @@ CLASS gemis_startImpl INHERITS WebHandler:
                     AND   webmenu.benutzer = ttInput.benutzer
                     AND   webmenu.sprcd    = INTEGER(ttInput.sprcd) :
                     
-                    CASE webmenu.Stufe:
+                    CASE webmenu.stufe2:
                         WHEN 0 THEN
                             DO:
                                 IF iAktStufe = 1 THEN
@@ -203,7 +203,7 @@ CLASS gemis_startImpl INHERITS WebHandler:
                                 END. 
                                 IF webmenu.menulink = '' THEN lcJsonString = lcJsonString + SUBSTITUTE('&1: &2', QUOTER(webmenu.Menutext), CHR(123)                ).
                                 ELSE                          lcJsonString = lcJsonString + SUBSTITUTE('&1: &2', QUOTER(webmenu.menutext), QUOTER(webmenu.menulink)).
-                                iAktStufe = webmenu.Stufe.
+                                iAktStufe = webmenu.stufe2.
                             END.
         
                         WHEN 1 THEN
@@ -215,7 +215,7 @@ CLASS gemis_startImpl INHERITS WebHandler:
                                 END.
                                 IF webmenu.menulink = '' THEN lcJsonString = lcJsonString + SUBSTITUTE('&1: &2', QUOTER(webmenu.menutext), CHR(123)).
                                 ELSE                          lcJsonString = lcJsonString + SUBSTITUTE('&1: &2', QUOTER(webmenu.menutext), QUOTER(webmenu.menulink)).
-                                iAktStufe = webmenu.Stufe.
+                                iAktStufe = webmenu.stufe1.
                             END.
         
                         WHEN 2 THEN
@@ -223,7 +223,7 @@ CLASS gemis_startImpl INHERITS WebHandler:
                                 IF iAktStufe = 2 THEN  lcJsonString = lcJsonString + ','.
                                 IF webmenu.menulink = '' THEN lcJsonString = lcJsonString + SUBSTITUTE('&1: &2', QUOTER(webmenu.menutext), CHR(123)                ).
                                 ELSE                          lcJsonString = lcJsonString + SUBSTITUTE('&1: &2', QUOTER(webmenu.menutext), QUOTER(webmenu.menulink)).
-                                iAktStufe = webmenu.Stufe.
+                                iAktStufe = webmenu.stufe1.
                             END.
         
                     END CASE.
@@ -257,17 +257,17 @@ CLASS gemis_startImpl INHERITS WebHandler:
                         AND   webmenu.sprcd    = INTEGER(ttInput.sprcd)
                         /*                        AND   webmenu.stufe    = iAktStufe - 1*/
                         AND   webmenu.menutext = ttInput.params NO-ERROR.
-                    ii = webmenu.Position.
+                    ii = webmenu.stufe1.
                 END.
 
                 FOR EACH webmenu NO-LOCK USE-INDEX webmenu-k1
                     WHERE webmenu.mandant  = ttInput.mandant
                     AND   webmenu.benutzer = ttInput.benutzer
                     AND   webmenu.sprcd    = INTEGER(ttInput.sprcd)
-                    AND   webmenu.Position > ii:
+                    AND   webmenu.stufe1   > ii:
 
-                    IF webmenu.stufe < iAktStufe THEN LEAVE.
-                    IF webmenu.stufe > iAktStufe THEN NEXT.
+                    IF webmenu.stufe2 < iAktStufe THEN LEAVE.
+                    IF webmenu.stufe2 > iAktStufe THEN NEXT.
 
                     IF webmenu.menulink = '' THEN lcJsonString = lcJsonString + SUBSTITUTE('&3&1:&2', QUOTER(webmenu.menutext), QUOTER(STRING(iAktStufe,"9")), cKomma  ).
                     ELSE                          lcJsonString = lcJsonString + SUBSTITUTE('&3&1:&2', QUOTER(webmenu.menutext), QUOTER(webmenu.menulink)     , cKomma ).

+ 0 - 28
adressen/isWorking.cls

@@ -1,28 +0,0 @@
- 
- /*------------------------------------------------------------------------
-    File        : isWorking
-    Purpose     : 
-    Syntax      : 
-    Description : 
-    Author(s)   : walter.riechsteiner
-    Created     : Mon Jun 23 17:46:00 CEST 2025
-    Notes       : 
-  ----------------------------------------------------------------------*/
-
-USING Progress.Lang.*.
-
-BLOCK-LEVEL ON ERROR UNDO, THROW.
-
-CLASS isWorking FINAL: 
-
-    /*------------------------------------------------------------------------------
-     Purpose:
-     Notes:
-    ------------------------------------------------------------------------------*/
-
-    CONSTRUCTOR PUBLIC isWorking (  ):
-        SUPER ().
-        
-    END CONSTRUCTOR.
-
-END CLASS.

+ 348 - 0
auth/loginImpl.cls

@@ -0,0 +1,348 @@
+ 
+/*------------------------------------------------------------------------
+   File        : adresse_dict
+   Purpose     : 
+   Syntax      : 
+   Description : 
+   Author(s)   : walter.riechsteiner
+   Created     : Thu Jun 26 13:56:20 CEST 2025
+   Notes       : 
+ ----------------------------------------------------------------------*/
+ 
+BLOCK-LEVEL ON ERROR UNDO, THROW.
+
+USING OpenEdge.Core.String FROM PROPATH.
+USING OpenEdge.Net.HTTP.IHttpResponse FROM PROPATH.
+USING OpenEdge.Net.HTTP.StatusCodeEnum FROM PROPATH.
+USING OpenEdge.Web.IWebRequest FROM PROPATH.
+USING OpenEdge.Web.WebHandler FROM PROPATH.
+USING OpenEdge.Web.WebResponseWriter FROM PROPATH.
+USING Progress.Json.ObjectModel.JsonObject FROM PROPATH.
+USING Progress.Json.ObjectModel.JsonArray FROM PROPATH.
+USING Progress.Json.ObjectModel.ObjectModelParser FROM PROPATH.
+USING src.ch.adprime.gemis.WebHandlerUtilities FROM PROPATH.
+USING utilities.utilitiesHandler FROM PROPATH.
+USING OpenEdge.Net.HTTP.HttpHeader FROM PROPATH.
+
+CLASS auth.loginImpl INHERITS WebHandler: 
+
+    DEFINE VARIABLE outilitiesHandler AS utilitiesHandler NO-UNDO.
+
+    DEFINE TEMP-TABLE tcompanies
+        SERIALIZE-NAME 'companies'
+        FIELD company      AS CHARACTER SERIALIZE-NAME 'company'
+        FIELD company_Name AS CHARACTER SERIALIZE-NAME 'company_name'
+        FIELD lselected    AS LOGICAL   SERIALIZE-NAME 'selected'
+        .
+        
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleGet (INPUT poRequest AS IWebRequest ):
+        DEFINE VARIABLE oResponse       AS IHttpResponse     NO-UNDO.         
+        DEFINE VARIABLE oWriter         AS WebResponseWriter NO-UNDO.
+        DEFINE VARIABLE oBody           AS String            NO-UNDO.
+        DEFINE VARIABLE oJsonResponse   AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsoncompanies  AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonArray      AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE cDefautlCharSet AS CHARACTER         NO-UNDO INIT 'UTF-8'.
+        DEFINE VARIABLE oParser         AS ObjectModelParser NO-UNDO.           
+        DEFINE VARIABLE cCorralationID  AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cContent-Type   AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE htcompanies     AS HANDLE            NO-UNDO.
+        DEFINE VARIABLE lcJsonInhalt    AS LONGCHAR          NO-UNDO.
+        DEFINE VARIABLE lOk             AS LOGICAL           NO-UNDO.
+        DEFINE VARIABLE ii              AS INTEGER           NO-UNDO.
+        
+        DEFINE VARIABLE cuser_name      AS CHARACTER         NO-UNDO.
+        
+        MESSAGE 'start get'.
+        cuser_name = poRequest:URI:GetQueryValue("user_name").
+        
+        ii = 0.
+        EMPTY TEMP-TABLE tcompanies.
+        FOR EACH companies NO-LOCK
+            WHERE companies.active = TRUE:
+            
+            ii = ii + 1.        
+            CREATE tcompanies.
+            ASSIGN 
+                tcompanies.company      = companies.company
+                tcompanies.company_Name = companies.company_name
+                tcompanies.lselected    = (IF ii = 1 THEN TRUE ELSE FALSE).
+        END.
+        
+        outilitiesHandler = NEW utilitiesHandler().
+
+        //  Ist dem Benutzer ein company zugeteilt ?
+        FIND FIRST users NO-LOCK
+            WHERE users.user_name = cuser_name NO-ERROR.
+        IF AVAILABLE users THEN 
+        DO:
+            FOR EACH tcompanies:
+                tcompanies.lselected = (IF tcompanies.company = users.company THEN TRUE ELSE FALSE).
+            END.
+        END.  
+                
+        htcompanies     = TEMP-TABLE tcompanies:DEFAULT-BUFFER-HANDLE.
+        cContent-Type   = "application/json".
+        cDefautlCharSet = 'utf-8'. 
+        oJsonResponse   = NEW JsonObject().
+        oParser         = NEW ObjectModelParser().
+        
+        oJsonResponse:ADD('user_name', cuser_name).
+
+        oJsoncompanies = NEW JsonObject().
+        htcompanies:WRITE-JSON('JsonObject', oJsoncompanies).
+        lcJsonInhalt   = oJsoncompanies:GetJsonText('companies').
+        oJsonArray     = CAST(oParser:Parse(lcJsonInhalt), JsonArray) NO-ERROR.
+        oJsonResponse:ADD('companies', oJsonArray) NO-ERROR.
+
+        oJsonResponse:WRITE(lcJsonInhalt, TRUE).
+        MESSAGE STRING(lcJsonInhalt).        
+        
+        oBody = NEW STRING(oJsonResponse:GetJsonText()).
+        WebHandlerUtilities:createHttpResponse(INPUT INTEGER(StatusCodeEnum:OK), INPUT oBody, INPUT cContent-Type, INPUT cDefautlCharSet, INPUT cCorralationID, OUTPUT oResponse).
+//        oResponse:SetHeader(HttpHeaderBuilder:Build(cHeaderCorralationID):Value(cCorralationID):Header).
+
+           
+        oWriter = NEW WebResponseWriter(oResponse).
+        oWriter:Open(). 
+        oWriter:Close(). 
+
+        RETURN 0.
+        
+        CATCH e AS Progress.Lang.Error:
+
+        END CATCH.
+
+        FINALLY:
+
+        END FINALLY.
+
+    END METHOD.
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleNotAllowedMethod(INPUT poRequest AS IWebRequest):
+        DEFINE VARIABLE result AS INTEGER NO-UNDO.
+        MESSAGE "HandleNotAllowedMethod called" VIEW-AS ALERT-BOX.
+        RETURN result.
+    END METHOD.
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleNotImplemented(INPUT poRequest AS IWebRequest):
+        DEFINE VARIABLE result AS INTEGER NO-UNDO.
+        MESSAGE "HandleNotImplemented called" VIEW-AS ALERT-BOX.
+        RETURN result.
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD OVERRIDE PROTECTED INTEGER HandlePost(INPUT poRequest AS IWebRequest):
+        
+        DEFINE VARIABLE oResponse      AS IHttpResponse                NO-UNDO.
+        DEFINE VARIABLE oWriter        AS WebResponseWriter            NO-UNDO.
+        DEFINE VARIABLE oParser        AS ObjectModelParser            NO-UNDO.           
+        DEFINE VARIABLE oJsonResponse  AS JsonObject                   NO-UNDO.
+        DEFINE VARIABLE oMessage       AS JsonObject                   NO-UNDO.
+        DEFINE VARIABLE oJsonData      AS JsonObject                   NO-UNDO.
+        DEFINE VARIABLE oJsonButtons   AS JsonObject                   NO-UNDO.
+
+        DEFINE VARIABLE lRetVal        AS LOGICAL                      NO-UNDO.
+        DEFINE VARIABLE lcJsonString   AS LONGCHAR                     NO-UNDO.
+        DEFINE VARIABLE i1             AS INTEGER                      NO-UNDO.
+
+        DEFINE VARIABLE cPasswort      AS CHARACTER                    NO-UNDO.
+        DEFINE VARIABLE cpassword      AS CHARACTER                    NO-UNDO.
+        DEFINE VARIABLE ccompany       AS CHARACTER                    NO-UNDO.
+        DEFINE VARIABLE cuser_name     AS CHARACTER                    NO-UNDO.
+        DEFINE VARIABLE ilanguage_id   AS INTEGER                      NO-UNDO.
+        DEFINE VARIABLE lcMessage      AS LONGCHAR                     NO-UNDO.
+        DEFINE VARIABLE lcErrorMessage AS LONGCHAR                     NO-UNDO.
+        DEFINE VARIABLE lError         AS LOGICAL                      NO-UNDO.
+        DEFINE VARIABLE cString        AS CHARACTER                    NO-UNDO.
+        DEFINE VARIABLE cMessage       AS CHARACTER                    NO-UNDO.
+        DEFINE VARIABLE csession_token AS CHARACTER                    NO-UNDO.
+        DEFINE VARIABLE rUsers         AS RECID                        NO-UNDO.
+
+        DEFINE VARIABLE poHeaders      AS HttpHeader                   NO-UNDO EXTENT.
+        DEFINE VARIABLE ix             AS INTEGER                      NO-UNDO.
+        DEFINE VARIABLE lcRetVal       AS LONGCHAR                     NO-UNDO.
+        DEFINE VARIABLE oHeader        AS OpenEdge.Net.HTTP.HttpHeader NO-UNDO.
+        MESSAGE 'start post'.        
+
+        lRetVal = WebHandlerUtilities:getJsonFromRequest(INPUT poRequest, OUTPUT oJsonData) NO-ERROR.
+        MESSAGE 'getJsonFromRequest    = ' lRetVal.
+
+        oJsonData:WRITE(lcJsonString, FALSE).
+        MESSAGE 'ganzer Eingangsstring = ' STRING(lcJsonString).
+
+        ccompany   = oJsonData:GetCharacter('company' ).
+        cuser_name = oJsonData:GetCharacter('user_name' ).
+        cpassword  = oJsonData:GetCharacter('password').
+        MESSAGE ccompany '-' cuser_name '-' cpassword.
+
+        lcErrorMessage    = ''.
+        lError            = FALSE.
+        outilitiesHandler = NEW utilitiesHandler().
+        
+        DO WHILE TRUE:
+            FIND FIRST users NO-LOCK
+                WHERE users.user_name = cuser_name
+                AND   users.active    = TRUE  NO-ERROR.
+            IF NOT AVAILABLE users THEN 
+            DO:
+                lError = TRUE.
+                outilitiesHandler:getErrorMessage (
+                    INPUT '1990',
+                    INPUT 1     ,           /* Sprcd*/
+                    INPUT ''    ,           /* Parameter  */
+                    OUTPUT lcMessage
+                    ).
+                LEAVE.
+            END.
+        
+            ilanguage_id = users.language_id.
+            rUsers       = RECID(users).
+            
+            IF users.password <> cpassword THEN 
+            DO:
+                lError = TRUE.
+                outilitiesHandler:getErrorMessage (
+                    INPUT '1992'      ,
+                    INPUT ilanguage_id,     /* Sprcd*/
+                    INPUT ''          ,     /* Parameter  */
+                    OUTPUT lcMessage
+                    ).
+                LEAVE.
+            END.
+            
+            FIND FIRST userauthorization NO-LOCK 
+                WHERE userauthorization.company   = ccompany
+                AND   userauthorization.user_name = cuser_name NO-ERROR.
+            IF NOT AVAILABLE userauthorization THEN 
+            DO:
+                lError = TRUE.
+                outilitiesHandler:getErrorMessage (
+                    INPUT '1991'      ,
+                    INPUT ilanguage_id,     /* Sprcd*/
+                    INPUT ''          ,     /* Parameter  */
+                    OUTPUT lcMessage
+                    ).
+                LEAVE.
+            END.
+
+            REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
+                csession_token = users.sha_password.
+                
+                IF users.sha_password <> '' THEN LEAVE.
+                IF users.password      = '' THEN cPasswort = users.user_name.
+                ELSE                             cPasswort = users.password. 
+                outilitiesHandler:generateHash (
+                    INPUT 'SHA-512',
+                    INPUT SUBSTITUTE('&1:&2', cPasswort, STRING(TIME,'99999999')),
+                    INPUT 'Passw0rd',
+                    OUTPUT lError,
+                    OUTPUT cMessage,
+                    OUTPUT csession_token
+                    ).
+                FIND users EXCLUSIVE-LOCK WHERE RECID(users) = rUsers.
+                ASSIGN
+                    users.sha_password = csession_token.
+                RELEASE users.
+                LEAVE.
+            END.
+            
+            FIND users NO-LOCK WHERE RECID(users) = rUsers.
+                        
+            /*            FIND FIRST userdata                                 */
+            /*                WHERE userdata.user_name   = cuser_name         */
+            /*                AND   userdata.company     = ccompany           */
+            /*                AND   userdata.record_type = 'LOGIN'            */
+            /*                AND   userdata.section     = 'company' NO-ERROR.*/
+            /*            IF NOT AVAILABLE userdata THEN                      */
+            /*            DO:                                                 */
+            /*                CREATE  userdata.                               */
+            /*                ASSIGN                                          */
+            /*                    userdata.user_name   = cuser_name           */
+            /*                    userdata.company     = ccompany             */
+            /*                    userdata.record_type = 'LOGIN'              */
+            /*                    userdata.section     = 'company'.           */
+            /*            END.                                                */
+            /*            ASSIGN                                              */
+            /*                userdata.cfield_1 = ccompany                    */
+            /*                userdata.cfield_2 = cuser_name                  */
+            /*                userdata.cfield_3 = csession_token.             */
+            /*                                                                */
+            /*            RELEASE userdata.                                   */
+            
+            oResponse             = NEW OpenEdge.Web.WebResponse().
+            oResponse:StatusCode  = INTEGER(StatusCodeEnum:OK).
+            oResponse:ContentType = "application/json;charset=utf-8".
+            oWriter               = NEW WebResponseWriter(oResponse).
+
+            FIND FIRST users NO-LOCK
+                WHERE users.user_name = cuser_name NO-ERROR.
+                
+            oJsonResponse = NEW JsonObject().
+            oJsonResponse:ADD('success'      , TRUE              ).
+            oJsonResponse:ADD('session_token', csession_token    ).
+            oJsonResponse:ADD('company'      , ccompany          ).
+            oJsonResponse:ADD('user_name'    , cuser_name        ).
+            oJsonResponse:ADD('display_name' , users.display_name).
+            oJsonResponse:ADD('language_id'  , ilanguage_id      ).
+            
+            oJsonButtons = NEW JsonObject().
+            FOR EACH labeltext NO-LOCK 
+                WHERE labeltexte.company     = ccompany
+                AND   labeltexte.program     = 'buttons'
+                AND   labeltexte.language_id = ilanguage_id:
+                oJsonButtons:ADD(labeltexte.field_name, labeltexte.sidelabel).
+            END.
+            oJsonResponse:ADD('labels', oJsonButtons).
+            
+            oJsonResponse:WRITE(lcJsonString, FALSE).
+            MESSAGE 'Rückmeldung ' STRING(lcJsonString).
+
+            oWriter:Open().
+            oWriter:Write(lcJsonString).
+            oWriter:Close().
+        
+            RETURN 0.
+
+        END.
+        
+        MESSAGE 'Meldung von getErrorMessage ' STRING(lcMessage).
+                        
+        oResponse             = NEW OpenEdge.Web.WebResponse().
+        oResponse:StatusCode  = INTEGER(StatusCodeEnum:OK).
+        oResponse:ContentType = "application/json;charset=utf-8".
+        oWriter               = NEW WebResponseWriter(oResponse).
+        
+        oJsonResponse = NEW JsonObject().
+        oJsonResponse:ADD('success', FALSE).
+        oJsonResponse:ADD('message', lcMessage) NO-ERROR.
+        
+        oJsonResponse:WRITE(lcJsonString, FALSE).
+        MESSAGE 'Rückmeldung ' STRING(lcJsonString).
+
+        oWriter:Open().
+        oWriter:Write(lcJsonString).
+        oWriter:Close().
+        
+        RETURN 0.
+
+        CATCH e AS Progress.Lang.Error:
+
+        END CATCH.
+
+        FINALLY:
+            DELETE OBJECT oParser NO-ERROR.
+        END FINALLY.
+
+    END METHOD.
+
+END CLASS.

+ 44 - 0
createWordIndex.p

@@ -0,0 +1,44 @@
+DEF VAR cwords AS CHAR NO-UNDO.
+DEF VAR ii AS INT NO-UNDO.
+DEF BUFFER bBuffer FOR labeltexte.
+DEF VAR hbBuffer AS HANDLE NO-UNDO.
+hbBuffer = BUFFER bBuffer:HANDLE.
+DEF VAR cDatatype AS CHAR NO-UNDO.
+DEF VAR cchar AS CHAR NO-UNDO.
+
+FOR EACH bBuffer:
+    cwords = ''.
+    DO ii = 1 TO hbBuffer:NUM-FIELDS:
+        IF hbBuffer:BUFFER-FIELD(ii):BUFFER-VALUE = ?         THEN NEXT.
+        IF hbBuffer:BUFFER-FIELD(ii):BUFFER-VALUE = ''        THEN NEXT.
+        IF hbBuffer:BUFFER-FIELD(ii):BUFFER-VALUE = '0'       THEN NEXT.
+        IF INDEX(hbBuffer:BUFFER-FIELD(ii):NAME, 'SHA')  > 0  THEN NEXT.
+        IF INDEX(hbBuffer:BUFFER-FIELD(ii):NAME, 'word') > 0  THEN NEXT.
+        
+        cDatatype = hbBuffer:BUFFER-FIELD(ii):DATA-TYPE.
+        CASE cDatatype:
+            WHEN 'logical'   THEN NEXT.
+            WHEN 'character' THEN cWords = cWords + ' ' + hbBuffer:BUFFER-FIELD(ii):BUFFER-VALUE.
+            WHEN 'integer'   THEN DO:
+                cchar  = TRIM(STRING(INTEGER(hbBuffer:BUFFER-FIELD(ii):BUFFER-VALUE),'zzzzzzzz9-')).
+                cwords = cWords + ' ' + CHR(01) + cChar + CHR(01).
+            END.
+            WHEN 'decimal'   THEN DO:
+                cchar  = TRIM(STRING(DECIMAL(hbBuffer:BUFFER-FIELD(ii):BUFFER-VALUE),'zzzzzzzz9.9<<<-')).
+                cwords = cWords + ' ' + CHR(01) + cChar + CHR(01).
+            END.
+            WHEN 'date'   THEN DO:
+                cchar  = STRING(DATE(hbBuffer:BUFFER-FIELD(ii):BUFFER-VALUE),'99.99.9999').
+                cwords = cWords + ' ' + cChar.
+            END.
+        END CASE.
+    END.
+    bBuffer.wordindex = ''.
+    cwords = TRIM(cwords).
+    DO ii = 1 TO NUM-ENTRIES(cwords, ' '):
+        cchar = ENTRY(ii, cwords, ' ').
+        IF LOOKUP(cchar, bBuffer.wordindex) > 0 THEN NEXT.
+        bBuffer.wordindex = bBuffer.wordindex + ' ' + cchar.
+    END.
+    bBuffer.wordindex = TRIM(bBuffer.wordindex).
+END.

+ 441 - 0
dashboard/dashboardImpl.cls

@@ -0,0 +1,441 @@
+ 
+/*------------------------------------------------------------------------
+   File        : adresse_dict
+   Purpose     : 
+   Syntax      : 
+   Description : 
+   Author(s)   : walter.riechsteiner
+   Created     : Thu Jun 26 13:56:20 CEST 2025
+   Notes       : 
+ ----------------------------------------------------------------------*/
+ 
+BLOCK-LEVEL ON ERROR UNDO, THROW.
+
+USING OpenEdge.Core.String FROM PROPATH.
+USING OpenEdge.Net.HTTP.IHttpResponse FROM PROPATH.
+USING OpenEdge.Net.HTTP.StatusCodeEnum FROM PROPATH.
+USING OpenEdge.Web.IWebRequest FROM PROPATH.
+USING OpenEdge.Web.WebHandler FROM PROPATH.
+USING OpenEdge.Web.WebResponseWriter FROM PROPATH.
+USING Progress.Json.ObjectModel.JsonObject FROM PROPATH.
+USING Progress.Json.ObjectModel.JsonArray FROM PROPATH.
+USING Progress.Json.ObjectModel.ObjectModelParser FROM PROPATH.
+USING src.ch.adprime.gemis.WebHandlerUtilities FROM PROPATH.
+USING utilities.utilitiesHandler FROM PROPATH.
+USING OpenEdge.Net.HTTP.HttpHeader FROM PROPATH.
+
+CLASS dashboard.dashboardImpl INHERITS WebHandler: 
+
+    DEFINE VARIABLE ccompany          AS CHARACTER        NO-UNDO.
+    DEFINE VARIABLE cuser_name        AS CHARACTER        NO-UNDO.
+    DEFINE VARIABLE cAnzeigeName      AS CHARACTER        NO-UNDO.
+    DEFINE VARIABLE ilanguage_id      AS INTEGER          NO-UNDO.
+    DEFINE VARIABLE cSessionToken     AS CHARACTER        NO-UNDO.
+    
+    DEFINE VARIABLE outilitiesHandler AS utilitiesHandler NO-UNDO.
+    
+    DEFINE TEMP-TABLE tcompanies
+        SERIALIZE-NAME 'companies'
+        FIELD company      AS CHARACTER SERIALIZE-NAME 'company'
+        FIELD company_name AS CHARACTER SERIALIZE-NAME 'company_name'
+        FIELD lSelected    AS LOGICAL   SERIALIZE-NAME 'selected'
+        .
+    DEFINE TEMP-TABLE tLevel1
+        SERIALIZE-NAME ''
+        FIELD menu_id      AS INTEGER 
+        FIELD menu_text    AS CHARACTER 
+        FIELD menu_link    AS CHARACTER
+        FIELD openMode     AS CHARACTER 
+        FIELD admin        AS LOGICAL 
+        FIELD level1_recid AS RECID     SERIALIZE-HIDDEN 
+        .
+    DEFINE TEMP-TABLE tLevel2
+        SERIALIZE-NAME 'children'
+        FIELD level1_recid AS RECID     SERIALIZE-HIDDEN 
+        FIELD menu_id      AS INTEGER 
+        FIELD menu_text    AS CHARACTER 
+        FIELD menu_link    AS CHARACTER 
+        FIELD openMode     AS CHARACTER 
+        FIELD admin        AS LOGICAL 
+        FIELD level2_recid AS RECID     SERIALIZE-HIDDEN 
+        .
+    DEFINE TEMP-TABLE tLevel3
+        SERIALIZE-NAME 'children'
+        FIELD level2_recid AS RECID     SERIALIZE-HIDDEN 
+        FIELD menu_id      AS INTEGER 
+        FIELD menu_text    AS CHARACTER 
+        FIELD menu_link    AS CHARACTER 
+        FIELD openMode     AS CHARACTER 
+        FIELD admin        AS LOGICAL 
+        FIELD level3_recid AS RECID     SERIALIZE-HIDDEN 
+        .
+    DEFINE DATASET menu_structur SERIALIZE-HIDDEN
+        FOR tLevel1, tLevel2, tLevel3
+
+        PARENT-ID-RELATION RELATION1 FOR tLevel1, tLevel2
+        PARENT-ID-FIELD level1_recid
+    
+        PARENT-ID-RELATION RELATION2 FOR tLevel2, tLevel3
+        PARENT-ID-FIELD level2_recid
+        .
+    DEFINE VARIABLE hDSmenu_structur AS HANDLE NO-UNDO.
+        
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleGet (INPUT poRequest AS IWebRequest ):
+        DEFINE VARIABLE oResponse       AS IHttpResponse                NO-UNDO.         
+        DEFINE VARIABLE oWriter         AS WebResponseWriter            NO-UNDO.
+        DEFINE VARIABLE oBody           AS String                       NO-UNDO.
+        DEFINE VARIABLE oJsonResponse   AS JsonObject                   NO-UNDO.
+        DEFINE VARIABLE oJsonMenu       AS JsonObject                   NO-UNDO.
+        DEFINE VARIABLE cDefautlCharSet AS CHARACTER                    NO-UNDO INIT 'UTF-8'.
+        DEFINE VARIABLE oParser         AS ObjectModelParser            NO-UNDO.           
+        DEFINE VARIABLE cContent-Type   AS CHARACTER                    NO-UNDO.
+        DEFINE VARIABLE cCorralationID  AS CHARACTER                    NO-UNDO.
+        DEFINE VARIABLE lcJsonInhalt    AS LONGCHAR                     NO-UNDO.
+        DEFINE VARIABLE lOk             AS LOGICAL                      NO-UNDO.
+        DEFINE VARIABLE ii              AS INTEGER                      NO-UNDO.
+        
+        DEFINE VARIABLE cFunction       AS CHARACTER                    NO-UNDO.
+        DEFINE VARIABLE cuser_name      AS CHARACTER                    NO-UNDO.
+        DEFINE VARIABLE lAdmin          AS LOGICAL                      NO-UNDO INIT FALSE.
+        DEFINE VARIABLE htwebmenu       AS HANDLE                       NO-UNDO.
+        DEFINE VARIABLE oHeader         AS OpenEdge.Net.HTTP.HttpHeader NO-UNDO.
+        DEFINE VARIABLE lRetVal         AS LOGICAL                      NO-UNDO.
+        DEFINE VARIABLE rtlevel1        AS RECID                        NO-UNDO.
+        DEFINE VARIABLE rtlevel2        AS RECID                        NO-UNDO.
+        DEFINE VARIABLE cnewuser_name   AS CHARACTER                    NO-UNDO.
+        
+        outilitiesHandler = NEW utilitiesHandler().
+        
+        outilitiesHandler:getHeaderData(
+            INPUT  poRequest    ,
+            OUTPUT ccompany     ,
+            OUTPUT cuser_name   ,
+            OUTPUT cAnzeigeName ,
+            OUTPUT ilanguage_id ,
+            OUTPUT cSessionToken
+            ).
+        
+        cFunction = poRequest:URI:GetQueryValue("function").
+        MESSAGE 'GET ' ccompany '-' cuser_name '-' cAnzeigeName '-' ilanguage_id '-' cFunction '-' cSessionToken.
+
+        lRetVal   = FALSE.
+        DO WHILE cFunction = 'init':
+            hDSmenu_structur = DATASET menu_structur:HANDLE.
+            
+            EMPTY TEMP-TABLE tlevel1.
+            EMPTY TEMP-TABLE tlevel2.
+            EMPTY TEMP-TABLE tlevel3.
+            
+            cnewuser_name = cuser_name.
+            lAdmin        = FALSE.
+            DO WHILE TRUE.
+                FIND FIRST webmenu NO-LOCK
+                    WHERE webmenu.company   = ccompany
+                    AND   webmenu.user_name = cnewuser_name NO-ERROR.
+                IF AVAILABLE webmenu    THEN LEAVE.
+                IF cnewuser_name = 'Admin' THEN LEAVE.
+            
+                cnewuser_name = 'Admin'.
+            END.
+        
+            FIND FIRST users NO-LOCK 
+                WHERE users.user_name = cnewuser_name NO-ERROR.
+            IF NOT AVAILABLE users THEN LEAVE.
+
+            lAdmin = users.lAdmin.         
+            FOR EACH webmenu NO-LOCK
+                WHERE webmenu.company   = ccompany
+                AND   webmenu.user_name = cnewuser_name
+                AND   webmenu.level1    > 0 :
+                
+                IF  NOT lAdmin              AND
+                    webmenu.menu_link <> '' AND
+                    webmenu.ladmin          THEN NEXT.
+                
+                IF webmenu.level2 = 0 THEN 
+                DO:
+                    CREATE  tlevel1.
+                    ASSIGN 
+                        tlevel1.level1_recid = RECID(tLevel1)
+                        tlevel1.menu_id      = webmenu.level1
+                        tlevel1.menu_text    = webmenu.menu_title
+                        tlevel1.menu_link    = webmenu.menu_link
+                        tlevel1.openMode     = webmenu.openmode
+                        tlevel1.admin        = webmenu.ladmin
+                        
+                        rtlevel1             = RECID(tlevel1).
+                    NEXT.
+                END.
+
+                IF webmenu.level3 = 0 THEN 
+                DO:
+                    CREATE  tlevel2.
+                    ASSIGN 
+                        tlevel2.level1_recid = rtlevel1
+                        tlevel2.level2_recid = RECID(tLevel2)
+                        tlevel2.menu_id      = webmenu.level2
+                        tlevel2.menu_text    = webmenu.menu_title
+                        tlevel2.menu_link    = webmenu.menu_link
+                        tlevel2.openmode     = webmenu.openmode
+                        tlevel2.admin        = webmenu.ladmin
+
+                        rtlevel2             = RECID(tlevel2).
+                    NEXT.
+                END.
+                CREATE  tlevel3.
+                ASSIGN 
+                    tlevel3.level2_recid = rtlevel2
+                    tlevel3.level3_recid = RECID(tLevel3)
+                    tlevel3.menu_id      = webmenu.level3
+                    tlevel3.menu_text    = webmenu.menu_title
+                    tlevel3.menu_link    = webmenu.menu_link
+                    tlevel3.openMode     = webmenu.openmode
+                    tlevel3.admin        = webmenu.ladmin
+                    .
+            END.
+
+            /*            htWebMenu = outilitiesHandler:getWebMenuStructure(*/
+            /*                INPUT ccompany ,                              */
+            /*                INPUT cuser_name,                             */
+            /*                INPUT ilanguage_id ) .                        */
+            
+            cContent-Type   = "application/json".
+            cDefautlCharSet = 'utf-8'. 
+            oJsonResponse   = NEW JsonObject().
+            oJsonMenu       = NEW JsonObject().
+            oJsonMenu:READ(hDSmenu_structur).
+            oJsonMenu:WRITE(lcJsonInhalt, FALSE).
+            ii = INDEX(lcJsonInhalt, '[').
+            lcJsonInhalt = SUBSTRING(lcJsonInhalt, ii).
+            ii = R-INDEX(lcJsonInhalt, ']').
+            lcJsonInhalt = SUBSTRING(lcJsonInhalt,01,ii).
+            MESSAGE STRING(lcJsonInhalt).
+            
+            lRetVal = TRUE.
+            LEAVE.
+        END.
+        
+        oBody = NEW STRING(lcJsonInhalt).
+        WebHandlerUtilities:createHttpResponse(INPUT INTEGER(StatusCodeEnum:OK), INPUT oBody, INPUT cContent-Type, INPUT cDefautlCharSet, INPUT cCorralationID, OUTPUT oResponse).
+//        oResponse:SetHeader(HttpHeaderBuilder:Build(cHeaderCorralationID):Value(cCorralationID):Header).
+
+           
+        oWriter = NEW WebResponseWriter(oResponse).
+        oWriter:Open(). 
+        oWriter:Close(). 
+
+        RETURN 0.
+        
+        CATCH e AS Progress.Lang.Error:
+
+        END CATCH.
+
+        FINALLY:
+
+        END FINALLY.
+
+    END METHOD.
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleNotAllowedMethod(INPUT poRequest AS IWebRequest):
+        DEFINE VARIABLE result AS INTEGER NO-UNDO.
+        MESSAGE "HandleNotAllowedMethod called" VIEW-AS ALERT-BOX.
+        RETURN result.
+    END METHOD.
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleNotImplemented(INPUT poRequest AS IWebRequest):
+        DEFINE VARIABLE result AS INTEGER NO-UNDO.
+        MESSAGE "HandleNotImplemented called" VIEW-AS ALERT-BOX.
+        RETURN result.
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD OVERRIDE PROTECTED INTEGER HandlePost(INPUT poRequest AS IWebRequest):
+        
+        DEFINE VARIABLE oResponse      AS IHttpResponse                NO-UNDO.
+        DEFINE VARIABLE oWriter        AS WebResponseWriter            NO-UNDO.
+        DEFINE VARIABLE oParser        AS ObjectModelParser            NO-UNDO.           
+        DEFINE VARIABLE oJsonResponse  AS JsonObject                   NO-UNDO.
+        DEFINE VARIABLE oMessage       AS JsonObject                   NO-UNDO.
+        DEFINE VARIABLE oJsonData      AS JsonObject                   NO-UNDO.
+
+        DEFINE VARIABLE lRetVal        AS LOGICAL                      NO-UNDO.
+        DEFINE VARIABLE lcJsonString   AS LONGCHAR                     NO-UNDO.
+        DEFINE VARIABLE i1             AS INTEGER                      NO-UNDO.
+
+        DEFINE VARIABLE lcMessage      AS LONGCHAR                     NO-UNDO.
+        DEFINE VARIABLE lcErrorMessage AS LONGCHAR                     NO-UNDO.
+        DEFINE VARIABLE lError         AS LOGICAL                      NO-UNDO.
+        DEFINE VARIABLE cString        AS CHARACTER                    NO-UNDO.
+
+        DEFINE VARIABLE oHeader        AS OpenEdge.Net.HTTP.HttpHeader NO-UNDO.
+        
+        oHeader      = poRequest:GetHeader('X-COMPANY').
+        ccompany     = oHeader:VALUE.
+        
+        oHeader      = poRequest:GetHeader('X-USER-NAME').
+        cuser_name    = oHeader:VALUE.
+        
+        oHeader      = poRequest:GetHeader('X-DISPLAY-NAME').
+        cAnzeigeName = oHeader:VALUE.
+        
+        oHeader = poRequest:GetHeader('X-LANGUAGE-ID').
+        ilanguage_id  = INTEGER(oHeader:VALUE).
+        
+        oHeader = poRequest:GetHeader('X-SESSION-TOKEN').
+        cSessionToken = oHeader:VALUE.
+
+        lRetVal = WebHandlerUtilities:getJsonFromRequest(INPUT poRequest, OUTPUT oJsonData) NO-ERROR.
+        MESSAGE 'getJsonFromRequest    = ' lRetVal.
+
+        oJsonData:WRITE(lcJsonString, FALSE).
+        MESSAGE 'ganzer Eingangsstring = ' STRING(lcJsonString).
+
+        MESSAGE ccompany '-' cuser_name '-' cSessionToken.
+
+        lcErrorMessage    = ''.
+        lError            = FALSE.
+        outilitiesHandler = NEW utilitiesHandler().
+        
+        DO WHILE TRUE:
+            FIND FIRST users NO-LOCK
+                WHERE users.user_name = cuser_name NO-ERROR.
+            /*            IF NOT AVAILABLE users THEN              */
+            /*            DO:                                      */
+            /*                lError = TRUE.                       */
+            /*                outilitiesHandler:getErrorMessage (  */
+            /*                    INPUT '1990',                    */
+            /*                    INPUT 1     , /* Sprcd*/         */
+            /*                    INPUT ''    ,    /* Parameter  */*/
+            /*                    OUTPUT lcMessage                 */
+            /*                    ).                               */
+            /*                LEAVE.                               */
+            /*            END.                                     */
+        
+            ilanguage_id = users.language_id.
+            
+            /*            IF users.password <> cPassword THEN      */
+            /*            DO:                                      */
+            /*                lError = TRUE.                       */
+            /*                outilitiesHandler:getErrorMessage (  */
+            /*                    INPUT '1992',                    */
+            /*                    INPUT ilanguage_id, /* Sprcd*/   */
+            /*                    INPUT ''    ,    /* Parameter  */*/
+            /*                    OUTPUT lcMessage                 */
+            /*                    ).                               */
+            /*                LEAVE.                               */
+            /*            END.                                     */
+            
+            FIND FIRST userauthorization NO-LOCK 
+                WHERE userauthorization.company   = ccompany
+                AND   userauthorization.user_name = cuser_name NO-ERROR.
+            /*            IF NOT AVAILABLE userauthorization THEN        */
+            /*            DO:                                            */
+            /*                lError = TRUE.                             */
+            /*                outilitiesHandler:getErrorMessage (        */
+            /*                    INPUT '1991'      ,                    */
+            /*                    INPUT ilanguage_id, /* Sprcd*/         */
+            /*                    INPUT ''          ,    /* Parameter  */*/
+            /*                    OUTPUT lcMessage                       */
+            /*                    ).                                     */
+            /*                LEAVE.                                     */
+            /*            END.                                           */
+
+            /*            REPEAT TRANSACTION ON ERROR UNDO, LEAVE:                */
+            /*                FIND FIRST userdata NO-LOCK                         */
+            /*                    WHERE userdata.user_name   = cuser_name         */
+            /*                    AND   userdata.record_type = 'LOGIN'            */
+            /*                    AND   userdata.key_type    = 'company' NO-ERROR.*/
+            /*                IF NOT AVAILABLE userdata THEN                      */
+            /*                DO:                                                 */
+            /*                    CREATE  userdata.                               */
+            /*                    ASSIGN                                          */
+            /*                        userdata.user_name   = cuser_name           */
+            /*                        userdata.record_type = 'LOGIN'              */
+            /*                        userdata.key_type    = 'company'.           */
+            /*                END.                                                */
+            /*                ASSIGN                                              */
+            /*                    userdata.cfield_1 = ccompany                    */
+            /*                    userdata.cfield_2 = cuser_name.                 */
+            /*                RELEASE userdata.                                   */
+            /*                LEAVE.                                              */
+            /*            END.                                                    */
+            
+            oResponse             = NEW OpenEdge.Web.WebResponse().
+            oResponse:StatusCode  = INTEGER(StatusCodeEnum:OK).
+            oResponse:ContentType = "application/json;charset=utf-8".
+            oWriter               = NEW WebResponseWriter(oResponse).
+
+            oJsonResponse = NEW JsonObject().
+            oJsonResponse:ADD('success'      , TRUE         ).
+            oJsonResponse:ADD('session_token', cSessionToken).
+            oJsonResponse:ADD('company'      , ccompany     ).
+            oJsonResponse:ADD('user_name'    , cuser_name   ).
+            oJsonResponse:ADD('language_id'  , ilanguage_id ).
+            
+            
+            oJsonResponse:WRITE(lcJsonString, FALSE).
+            MESSAGE 'Rückmeldung ' STRING(lcJsonString).
+
+            oWriter:Open().
+            oWriter:Write(lcJsonString).
+            oWriter:Close().
+        
+            RETURN 0.
+
+        END.
+        
+        MESSAGE 'Meldung von getErrorMessage ' STRING(lcMessage).
+                        
+        oResponse             = NEW OpenEdge.Web.WebResponse().
+        oResponse:StatusCode  = INTEGER(StatusCodeEnum:OK).
+        oResponse:ContentType = "application/json;charset=utf-8".
+        oWriter               = NEW WebResponseWriter(oResponse).
+        
+        oParser       = NEW ObjectModelParser().
+        oJsonResponse = NEW JsonObject().
+        oJsonResponse:ADD('success', FALSE).
+        oJsonResponse:ADD('message', 'ungültiger users oder ungültiges Passwort!') NO-ERROR.
+        oJsonResponse:WRITE(lcJsonString, TRUE).
+        
+        MESSAGE 'Rückmeldung ' STRING(lcJsonString).
+
+        oWriter:Open().
+        oWriter:Write(lcJsonString).
+        oWriter:Close().
+        
+        RETURN 0.
+
+        CATCH e AS Progress.Lang.Error:
+
+        END CATCH.
+
+        FINALLY:
+            DELETE OBJECT oParser NO-ERROR.
+        END FINALLY.
+
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD PUBLIC LOGICAL POSTDATAFILLDS( 
+        INPUT iphDS AS HANDLE 
+        ):
+            
+        
+        RETURN TRUE.
+
+    END METHOD.
+
+END CLASS.

+ 154 - 0
formdesigner/getTableFIeldsImpl.cls

@@ -0,0 +1,154 @@
+ 
+/*------------------------------------------------------------------------
+   File        : adresse_dict
+   Purpose     : 
+   Syntax      : 
+   Description : 
+   Author(s)   : walter.riechsteiner
+   Created     : Thu Jun 26 13:56:20 CEST 2025
+   Notes       : 
+ ----------------------------------------------------------------------*/
+ 
+BLOCK-LEVEL ON ERROR UNDO, THROW.
+
+USING OpenEdge.Core.String FROM PROPATH.
+USING OpenEdge.Net.HTTP.IHttpResponse FROM PROPATH.
+USING OpenEdge.Net.HTTP.StatusCodeEnum FROM PROPATH.
+USING OpenEdge.Web.IWebRequest FROM PROPATH.
+USING OpenEdge.Web.WebHandler FROM PROPATH.
+USING OpenEdge.Web.WebResponseWriter FROM PROPATH.
+USING Progress.Json.ObjectModel.JsonObject FROM PROPATH.
+USING Progress.Json.ObjectModel.JsonArray FROM PROPATH.
+USING src.ch.adprime.gemis.WebHandlerUtilities FROM PROPATH.
+USING src.ch.adprime.gemis.ErrorMessage FROM PROPATH.
+
+CLASS getTableFieldsImpl INHERITS WebHandler: 
+
+    DEFINE TEMP-TABLE tFileDict
+        SERIALIZE-NAME 'fields'
+        FIELD cName      AS CHARACTER SERIALIZE-NAME 'fieldName'
+        FIELD cLabel     AS CHARACTER SERIALIZE-NAME 'label' 
+        FIELD cType      AS CHARACTER SERIALIZE-NAME 'type'
+        FIELD iMaxLength AS INTEGER   SERIALIZE-NAME 'maxLength'
+        FIELD cFormat    AS CHARACTER SERIALIZE-NAME 'format'
+        FIELD lReadOnly  AS LOGICAL   SERIALIZE-NAME 'editable'
+        FIELD lhidden    AS LOGICAL   SERIALIZE-NAME 'hidden'
+        .
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleGet (INPUT poRequest AS IWebRequest ):
+        DEFINE VARIABLE oResponse       AS IHttpResponse     NO-UNDO.         
+        DEFINE VARIABLE oWriter         AS WebResponseWriter NO-UNDO.
+        DEFINE VARIABLE oError          AS ErrorMessage      NO-UNDO.
+        DEFINE VARIABLE oBody           AS String            NO-UNDO.
+        DEFINE VARIABLE oJsonResponse   AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonArray      AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE lDebug          AS LOGICAL           NO-UNDO.
+        DEFINE VARIABLE cDefautlCharSet AS CHARACTER         NO-UNDO INIT 'UTF-8'.
+           
+        DEFINE VARIABLE cCorralationID  AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cContent-Type   AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE htFileDict      AS HANDLE            NO-UNDO.
+        DEFINE VARIABLE lcJsonInhalt    AS LONGCHAR          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 cFileName       AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cFileNames      AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cFelder         AS CHARACTER         NO-UNDO.
+        
+        cFileNames = poRequest:URI:GetQueryValue("tables").
+        MESSAGE 'File-Names = ' cFileNames.
+        
+        cFileNames = REPLACE(cFileNames, ',', ';').
+        DO ii = 1 TO NUM-ENTRIES(cFileNames, ';'):
+            cFileName = ENTRY(ii,cFileNames, ';').
+            FIND FIRST AnaDat._File NO-LOCK 
+                WHERE AnaDat._File._File-Name = cFileName NO-ERROR.
+                
+            FOR EACH AnaDat._Field OF AnaDat._File:
+                CREATE tFileDict.
+                ASSIGN
+                    tFileDict.cName      = AnaDat._File._File-Name + '.' + AnaDat._Field._Field-Name
+                    tFileDict.cType      = AnaDat._Field._Data-Type
+                    tFileDict.cFormat    = AnaDat._Field._Format
+                    tFileDict.lhidden    = FALSE
+                    tFileDict.lReadOnly  = FALSE
+                    tFileDict.iMaxLength = 10.
+
+                FIND FIRST labeltexte NO-LOCK 
+                    WHERE labeltexte.mandant  = '1000'
+                    AND   labeltexte.benutzer = ''
+                    AND   labeltexte.program  = ''
+                    AND   labeltexte.feld     = Anadat._Field._Field-Name
+                    AND   labeltexte.sprcd    = 1 NO-ERROR.
+
+                IF AVAILABLE labeltexte THEN 
+                DO:
+                    tFileDict.cLabel = labeltexte.sidelabel.
+                END.
+                ELSE 
+                DO:
+                    tFileDict.cLabel = (IF AnaDat._Field._Label <> ? THEN AnaDat._Field._Label ELSE AnaDat._Field._Field-Name). 
+                END.
+
+                IF INDEX(AnaDat._Field._Format, '(') = 0 THEN tFileDict.iMaxLength = LENGTH(AnaDat._Field._Format).
+                ELSE 
+                DO:
+                    i1 = INDEX(AnaDat._Field._Format, '(') + 1.
+                    i2 = INDEX(AnaDat._Field._Format, ')').
+                    tFileDict.iMaxLength = INTEGER(SUBSTRING(_Field._Format, i1, i2 - i1)).
+                END.
+
+            END.
+        END.
+        
+        htFileDict = TEMP-TABLE tFileDict:DEFAULT-BUFFER-HANDLE.
+                 
+        cContent-Type   = "application/json".
+        cDefautlCharSet = 'utf-8'. 
+        oJsonArray      = NEW JsonArray().
+        oJsonResponse   = NEW JsonObject().
+        MESSAGE '1'.
+        htFileDict:WRITE-JSON("JsonArray", oJsonArray).
+        htFileDict:WRITE-JSON("JsonObject", oJsonResponse).
+
+        MESSAGE "GetHandler" STRING(lcJsonInhalt).
+          
+//        oBody = NEW String(oJsonResponse:GetJsonText()).         
+        oBody = NEW String(oJsonResponse:GetJsonText()).         
+        WebHandlerUtilities:createHttpResponse(INPUT INTEGER(StatusCodeEnum:OK), INPUT oBody, INPUT cContent-Type, INPUT cDefautlCharSet, INPUT cCorralationID, OUTPUT oResponse).
+//        oResponse:SetHeader(HttpHeaderBuilder:Build(cHeaderCorralationID):Value(cCorralationID):Header).
+           
+        oWriter = NEW WebResponseWriter(oResponse).
+        oWriter:Open(). 
+        oWriter:Close(). 
+            
+        RETURN 0.
+        
+        CATCH e AS Progress.Lang.Error:
+
+        END CATCH.
+
+        FINALLY:
+
+        END FINALLY.
+
+    END METHOD.
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleNotAllowedMethod(INPUT poRequest AS IWebRequest):
+        DEFINE VARIABLE result AS INTEGER NO-UNDO.
+        MESSAGE "HandleNotAllowedMethod called" VIEW-AS ALERT-BOX.
+        RETURN result.
+    END METHOD.
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleNotImplemented(INPUT poRequest AS IWebRequest):
+        DEFINE VARIABLE result AS INTEGER NO-UNDO.
+        MESSAGE "HandleNotImplemented called" VIEW-AS ALERT-BOX.
+        RETURN result.
+    END METHOD.
+
+END CLASS.

+ 166 - 0
formdesigner/initialDataImpl.cls

@@ -0,0 +1,166 @@
+ 
+/*------------------------------------------------------------------------
+   File        : adresse_dict
+   Purpose     : 
+   Syntax      : 
+   Description : 
+   Author(s)   : walter.riechsteiner
+   Created     : Thu Jun 26 13:56:20 CEST 2025
+   Notes       : 
+ ----------------------------------------------------------------------*/
+ 
+BLOCK-LEVEL ON ERROR UNDO, THROW.
+
+USING OpenEdge.Core.String FROM PROPATH.
+USING OpenEdge.Net.HTTP.IHttpResponse FROM PROPATH.
+USING OpenEdge.Net.HTTP.StatusCodeEnum FROM PROPATH.
+USING OpenEdge.Web.IWebRequest FROM PROPATH.
+USING OpenEdge.Web.WebHandler FROM PROPATH.
+USING OpenEdge.Web.WebResponseWriter FROM PROPATH.
+USING Progress.Json.ObjectModel.JsonObject FROM PROPATH.
+USING Progress.Json.ObjectModel.JsonArray FROM PROPATH.
+USING src.ch.adprime.gemis.WebHandlerUtilities FROM PROPATH.
+USING utilities.utilitiesHandler FROM PROPATH.
+
+CLASS formdesigner.initialDataImpl INHERITS WebHandler: 
+
+    DEFINE VARIABLE outilitiesHandler AS utilitiesHandler NO-UNDO.
+    
+    DEFINE TEMP-TABLE tcompanies
+        SERIALIZE-NAME 'companies'
+        FIELD company      AS CHARACTER SERIALIZE-NAME 'company' 
+        FIELD company_name AS CHARACTER SERIALIZE-NAME 'company_name'
+        .
+    DEFINE VARIABLE htcompanies AS HANDLE NO-UNDO.
+    
+    DEFINE TEMP-TABLE tusers
+        SERIALIZE-NAME 'users'
+        FIELD user_name    AS CHARACTER SERIALIZE-NAME 'user-name' 
+        FIELD display_name AS CHARACTER SERIALIZE-NAME 'display_name'
+        .
+    DEFINE VARIABLE htusers AS HANDLE NO-UNDO.
+        
+    DEFINE TEMP-TABLE tlanguages
+        SERIALIZE-NAME 'languages'
+        FIELD language_id   AS INTEGER   SERIALIZE-NAME 'id' 
+        FIELD language_name AS CHARACTER SERIALIZE-NAME 'text'
+        .
+    DEFINE VARIABLE htlanguages AS HANDLE NO-UNDO.
+        
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleGet (INPUT poRequest AS IWebRequest ):
+        DEFINE VARIABLE oResponse       AS IHttpResponse     NO-UNDO.         
+        DEFINE VARIABLE oWriter         AS WebResponseWriter NO-UNDO.
+        DEFINE VARIABLE oBody           AS String            NO-UNDO.
+        DEFINE VARIABLE oJsonArray      AS JsonArray         NO-UNDO.
+        DEFINE VARIABLE oJsonMandant    AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonBenutzer   AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE oJsonlanguages  AS JsonObject        NO-UNDO.
+        DEFINE VARIABLE cDefautlCharSet AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cContentType    AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE cCorralationId  AS CHARACTER         NO-UNDO.
+           
+        DEFINE VARIABLE lcJsonInhalt    AS LONGCHAR          NO-UNDO.
+        DEFINE VARIABLE ccompany        AS CHARACTER         NO-UNDO.
+        DEFINE VARIABLE ii              AS INTEGER           NO-UNDO.
+        
+        MESSAGE 'start get'.
+        
+        EMPTY TEMP-TABLE tcompanies .
+        EMPTY TEMP-TABLE tusers.
+        EMPTY TEMP-TABLE tlanguages .
+        
+        ii = 0.
+        FOR EACH companies NO-LOCK 
+            WHERE companies.active = TRUE:
+            ii = ii + 1.
+            
+            CREATE  tcompanies.
+            BUFFER-COPY companies TO tcompanies.
+            IF ii = 1 THEN ccompany = companies.company.
+        END.
+        
+        CREATE  tusers.
+        ASSIGN 
+            tusers.user_name     = 'Admin'
+            tusers.display_name  = 'alle Benutzer (Default/admin)'.
+        FOR EACH users NO-LOCK
+            WHERE users.company = ccompany:
+                
+            IF users.user_name = 'Admin' THEN NEXT.
+                
+            CREATE  tusers.
+            BUFFER-COPY users TO tusers.
+        END.
+        
+        FOR EACH languages NO-LOCK:
+            CREATE  tlanguages.
+            BUFFER-COPY LANGUAGES TO tlanguages.
+        END.
+        
+        cContentType    = 'application/json'.
+        cDefautlCharSet = 'utf-8'.
+
+        oJsonMandant   = NEW JsonObject().
+        oJsonBenutzer  = NEW JsonObject().
+        oJsonlanguages = NEW JsonObject().
+        
+        htcompanies = TEMP-TABLE tcompanies:DEFAULT-BUFFER-HANDLE.
+        htusers     = TEMP-TABLE tusers    :DEFAULT-BUFFER-HANDLE.
+        htlanguages = TEMP-TABLE tlanguages:DEFAULT-BUFFER-HANDLE.
+
+        outilitiesHandler = NEW utilitiesHandler ().
+        htcompanies :WRITE-JSON("JsonObject", oJsonMandant ).
+        htusers:WRITE-JSON("JsonObject", oJsonBenutzer).
+        htlanguages :WRITE-JSON("JsonObject", oJsonlanguages ).
+
+        lcJsonInhalt
+        = CHR(123)  /* "{" */
+            + outilitiesHandler:trimStructure(INPUT oJsonMandant)
+            + ', '
+            + outilitiesHandler:trimStructure(INPUT oJsonBenutzer)
+            + ', '
+            + outilitiesHandler:trimStructure(INPUT oJsonlanguages)
+            + CHR(125).   /* "}" */
+
+        oBody = NEW String(lcJsonInhalt).
+        MESSAGE STRING(oBody).
+        
+        WebHandlerUtilities:createHttpResponse(INPUT INTEGER(StatusCodeEnum:OK), INPUT oBody, INPUT cContentType, INPUT cDefautlCharSet, INPUT cCorralationID, OUTPUT oResponse).
+        
+        oWriter = NEW WebResponseWriter(oResponse).
+        oWriter:Open(). 
+        oWriter:Close(). 
+            
+        RETURN 0.
+        
+        CATCH e AS Progress.Lang.Error:
+
+        END CATCH.
+
+        FINALLY:
+            DELETE OBJECT oJsonMandant     .
+            DELETE OBJECT oJsonBenutzer    .
+            DELETE OBJECT oJsonlanguages     .
+            DELETE OBJECT outilitiesHandler.
+        END FINALLY.
+
+    END METHOD.
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleNotAllowedMethod(INPUT poRequest AS IWebRequest):
+        DEFINE VARIABLE result AS INTEGER NO-UNDO.
+        MESSAGE "HandleNotAllowedMethod called" VIEW-AS ALERT-BOX.
+        RETURN result.
+    END METHOD.
+
+    METHOD OVERRIDE PROTECTED INTEGER HandleNotImplemented(INPUT poRequest AS IWebRequest):
+        DEFINE VARIABLE result AS INTEGER NO-UNDO.
+        MESSAGE "HandleNotImplemented called" VIEW-AS ALERT-BOX.
+        RETURN result.
+    END METHOD.
+
+END CLASS.

+ 8 - 144
isWorkingImpl.cls

@@ -30,6 +30,7 @@ CLASS isWorkingImpl INHERITS WebHandler:
         FIELD cType   AS CHARACTER SERIALIZE-NAME 'type'
         FIELD iLaenge AS INTEGER   SERIALIZE-NAME 'width'
         .
+        
     /*------------------------------------------------------------------------------
      Purpose:
      Notes:
@@ -53,52 +54,15 @@ CLASS isWorkingImpl INHERITS WebHandler:
         DEFINE VARIABLE cFileName       AS CHARACTER         NO-UNDO.
         DEFINE VARIABLE cFelder         AS CHARACTER         NO-UNDO.
         
-/*        cFileName = poRequest:URI:GetQueryValue("File").                       */
-/*        MESSAGE 'File-Name = ' cFileName.                                      */
-/*                                                                               */
-/*        FIND FIRST AnaDat._File NO-LOCK                                        */
-/*            WHERE AnaDat._File._File-Name = cFileName NO-ERROR.                */
-/*        FOR EACH AnaDat._Field OF AnaDat._File:                                */
-/*            CREATE tFileDIct.                                                  */
-/*            ASSIGN                                                             */
-/*                tFileDIct.cName   = AnaDat._Field._Field-Name                  */
-/*                tFileDIct.cType   = REPLACE(AnaDat._Field._Data-Type, '-', '_')*/
-/*                tFileDIct.iLaenge = 10.                                        */
-/*            CASE AnaDat._Field._Data-Type:                                     */
-/*                WHEN 'logical' THEN                                            */
-/*                    tFileDIct.cType   = 'checkbox'.                            */
-/*                WHEN 'character' THEN                                          */
-/*                    tFileDIct.cType   = 'text'.                                */
-/*                WHEN 'integer' THEN                                            */
-/*                    tFileDIct.cType   = 'number'.                              */
-/*                WHEN 'logical' THEN                                            */
-/*                    tFileDIct.cType   = 'checkbox'.                            */
-/*            END CASE.                                                          */
-/*        END.                                                                   */
-/*        htFileDIct = TEMP-TABLE tFileDIct:DEFAULT-BUFFER-HANDLE.               */
-/*                                                                               */
-        cContent-Type = "plain/text".
-           
-        oError = NEW ErrorMessage().
-        oError:lDebug = lDebug.
-          
-/*        oJsonResponse = NEW JsonObject().                  */
-/*        htFileDict:WRITE-JSON('JsonObject', oJsonResponse).*/
-/*                                                           */
-/*        oJsonResponse:WRITE(lcJsonInhalt, FALSE).          */
-        /*        ii = INDEX(lcJsonInhalt, '[').                 */
-        /*        lcJsonInhalt = SUBSTRING(lcJsonInhalt, ii).    */
-        /*                                                       */
-        /*        ii = R-INDEX(lcJsonInhalt, ']').               */
-        /*        lcJsonInhalt = SUBSTRING(lcJsonInhalt, 01, ii).*/
+        MESSAGE 'start get'.
+        
+        oBody           = NEW String('GET is working').
+        cContent-Type   = 'plain/text'.
+        cDefautlCharSet = 'utf-8'.
 
-        MESSAGE "GetHandler".
-          
-//        oBody = NEW String(oJsonResponse:GetJsonText()).         
-        oBody = NEW String('GET OK').         
         WebHandlerUtilities:createHttpResponse(INPUT INTEGER(StatusCodeEnum:OK), INPUT oBody, INPUT cContent-Type, INPUT cDefautlCharSet, INPUT cCorralationID, OUTPUT oResponse).
 //        oResponse:SetHeader(HttpHeaderBuilder:Build(cHeaderCorralationID):Value(cCorralationID):Header).
-           
+        
         oWriter = NEW WebResponseWriter(oResponse).
         oWriter:Open(). 
         oWriter:Close(). 
@@ -133,112 +97,12 @@ CLASS isWorkingImpl INHERITS WebHandler:
 
         MESSAGE "Entering HandlePost" VIEW-AS ALERT-BOX.
         
-/*        lRetVal = WebHandlerUtilities:getJsonFromRequest(INPUT poRequest, OUTPUT oJsonData) NO-ERROR.       */
-/*        oJsonData:WRITE(lcJsonString, FALSE).                                                               */
-/*        //                                                                                                  */
-/*        //  Input-Daten (Steuersatz) aus JsonObject lesen und in ttInput füllen                             */
-/*        //                                                                                                  */
-/*        EMPTY TEMP-TABLE ttInput    .                                                                       */
-/*        hbttInput = TEMP-TABLE ttInput:DEFAULT-BUFFER-HANDLE.                                               */
-/*        oInput    = NEW JsonObject().                                                                       */
-/*        oInput    = oJsonData:GetJsonObject('ttInput').                                                     */
-/*        lRetVal   = hbttInput:READ-JSON ('JsonObject', oInput).                                             */
-/*                                                                                                            */
-/*        FIND FIRST ttInput.                                                                                 */
-/*        cAktion = ttInput.action.                                                                           */
-/*                                                                                                            */
-/*        outilitiesHandler = NEW utilitiesHandler().                                                         */
-/*                                                                                                            */
-/*        DO WHILE lRetVal:                                                                                   */
-/*            hbttInput    = TEMP-TABLE ttInput   :DEFAULT-BUFFER-HANDLE.                                     */
-/*            hbttMandant  = TEMP-TABLE ttMandant :DEFAULT-BUFFER-HANDLE.                                     */
-/*                                                                                                            */
-/*            MESSAGE 'Inputdaten gelesen mit returncode ' lRetVal.                                           */
-/*            IF NOT lRetVal THEN LEAVE.                                                                      */
-/*                                                                                                            */
-/*            FIND FIRST ttInput.                                                                             */
-/*                                                                                                            */
-/*            IF ttInput.action = 'first' THEN                                                                */
-/*            DO:                                                                                             */
-/*                EMPTY TEMP-TABLE ttMandant.                                                                 */
-/*                FOR EACH Mandant NO-LOCK                                                                    */
-/*                    WHERE Mandant.Zustand = TRUE:                                                           */
-/*                    CREATE  ttMandant.                                                                      */
-/*                    ASSIGN                                                                                  */
-/*                        ttMandant.Mandant     = Mandant.Firma                                               */
-/*                        ttMandant.Bezeichnung = Mandant.Name.                                               */
-/*                /*                    ttMandant.choose      = (IF Mandant = '2000' THEN '1' ELSE '0').*/    */
-/*                END.                                                                                        */
-/*                                                                                                            */
-/*                oJsonData = NEW JsonObject().                                                               */
-/*                hbttMandant:WRITE-JSON('JsonObject', oJsonData).                                            */
-/*                oJsonData:WRITE(lcJsonString, TRUE).                                                        */
-/*            END.                                                                                            */
-/*                                                                                                            */
-/*            IF ttInput.action = 'anmelden' THEN                                                             */
-/*            DO:                                                                                             */
-/*                oJsonData:WRITE(lcJsonString, FALSE).                                                       */
-/*                                                                                                            */
-/*                FIND FIRST ttInput.                                                                         */
-/*                                                                                                            */
-/*                IF INDEX(ttInput.benutzer, '_Admin') > 0 THEN                                               */
-/*                DO:                                                                                         */
-/*                    ttInput.benutzer = REPLACE(ttInput.benutzer, '_Admin', '').                             */
-/*                    lAdmin = TRUE.                                                                          */
-/*                END.                                                                                        */
-/*                                                                                                            */
-/*                IF NOT lAdmin THEN                                                                          */
-/*                DO:                                                                                         */
-/*                    FIND Benutzer NO-LOCK                                                                   */
-/*                        WHERE Benutzer.Firma    = ttInput.mandant                                           */
-/*                        AND   Benutzer.Benutzer = ttInput.benutzer                                          */
-/*                        AND   Benutzer.Kennwort = ttInput.password NO-ERROR.                                */
-/*                END.                                                                                        */
-/*                ELSE                                                                                        */
-/*                DO:                                                                                         */
-/*                    FIND FIRST Benutzer NO-LOCK                                                             */
-/*                        WHERE Benutzer.Firma    = ttInput.mandant                                           */
-/*                        AND   Benutzer.Benutzer = ttInput.benutzer NO-ERROR.                                */
-/*                END.                                                                                        */
-/*                IF NOT AVAILABLE (Benutzer) THEN                                                            */
-/*                DO:                                                                                         */
-/*                    outilitiesHandler:getErrorMessage(INPUT '1990', INPUT 1, INPUT '', OUTPUT lcJsonString).*/
-/*                                                                                                            */
-/*                    oResponse = NEW OpenEdge.Web.WebResponse().                                             */
-/*                    oResponse:StatusCode  = INTEGER(StatusCodeEnum:OK).                                     */
-/*                    oResponse:ContentType = "application/json;charset=utf-8".                               */
-/*                    oWriter = NEW WebResponseWriter(oResponse).                                             */
-/*                    oWriter:Open().                                                                         */
-/*                    MESSAGE 'lcString Rückgabe: ' + STRING(lcJsonString) VIEW-AS ALERT-BOX.                 */
-/*                    oWriter:Write(lcJsonString).                                                            */
-/*                    oWriter:Close().                                                                        */
-/*                    RETURN -1.                                                                              */
-/*                END.                                                                                        */
-/*                                                                                                            */
-/*                ttInput.action = 'return'.                                                                  */
-/*                ttInput.link   = 'gemis_start.html'.                                                        */
-/*                ttInput.sprcd  = STRING(Benutzer.Sprcd).                                                    */
-/*                                                                                                            */
-/*                lcJsonString = ''.                                                                          */
-/*                DO ii = 1 TO hbttInput:NUM-FIELDS:                                                          */
-/*                    lcJsonString = lcJsonString                                                             */
-/*                        + (IF lcJsonString = '' THEN '' ELSE ', ')                                          */
-/*                        + QUOTER(hbttInput:BUFFER-FIELD(ii):NAME)                                           */
-/*                        + ': '                                                                              */
-/*                        + QUOTER(hbttInput:BUFFER-FIELD(ii):BUFFER-VALUE).                                  */
-/*                END.                                                                                        */
-/*                lcJsonString = CHR(123) + lcJsonString + chr(125).                                          */
-/*                MESSAGE 'Return-Daten nach füllen aus ttInput ' STRING(lcJsonString).                       */
-/*            END.                                                                                            */
-/*            LEAVE.                                                                                          */
-/*        END.                                                                                                */
-
         oResponse = NEW OpenEdge.Web.WebResponse().
         oResponse:StatusCode = INTEGER(StatusCodeEnum:OK).
         oResponse:ContentType = "plain/text;charset=utf-8".
         oWriter = NEW WebResponseWriter(oResponse).
         oWriter:Open().
-        MESSAGE 'POST is working' + STRING(lcJsonString) VIEW-AS ALERT-BOX.
+        MESSAGE 'POST is working'.
         oWriter:Write('POST is working').
         oWriter:Close().
 

+ 62 - 0
update/update2webdb.p

@@ -0,0 +1,62 @@
+ FOR EACH benutzer:
+    FIND users
+        WHERE users.user_name  = benutzer.benutzer NO-ERROR.
+    IF NOT AVAILABLE users THEN
+    DO:
+        CREATE  users.
+        ASSIGN
+            users.user_name  = benutzer.benutzer.
+    END.
+    ASSIGN
+        users.display_name = benutzer.anzeige
+        users.ROLE = (IF benutzer.admin THEN 'admin' ELSE 'user')
+        users.ACTIVE = TRUE
+        users.language_id = benutzer.sprcd
+        users.company = benutzer.firma
+        .
+ END.
+
+ FOR EACH Sprache:
+    FIND LANGUAGES
+        WHERE LANGUAGES.language_id = Sprache.Sprcd.
+    IF NOT AVAILABLE LANGUAGES THEN
+    DO:
+        CREATE  LANGUAGES.
+        ASSIGN  LANGUAGES.language_id = Sprache.Sprcd.
+    END.
+    ASSIGN
+        LANGUAGES.LANGUAGE_name = Sprache.Bez.
+END.
+
+FOR EACH Mandant:
+    FIND companies
+        WHERE companies.company = Mandant.Firma.
+    IF NOT AVAILABLE companies THEN
+    DO:
+        CREATE  companies.
+        ASSIGN  companies.company = Mandant.Firma.
+    END.
+    ASSIGN
+        companies.company_name = Mandant.NAME.
+END.
+
+FOR EACH Berecht:
+    FIND userauthorization
+        WHERE userauthorization.company = berecht.mandant
+        AND   userauthorization.user_name = berecht.benutzer
+        AND   userauthorization.program = berecht.programm NO-ERROR.
+    IF NOT AVAILABLE userauthorization THEN
+    DO:
+        CREATE  userauthorization.
+        ASSIGN
+            userauthorization.company = berecht.mandant
+            userauthorization.user_name = berecht.benutzer
+            userauthorization.program = berecht.programm.
+    END.
+    ASSIGN
+        userauthorization.lcreate   = berecht.pwe
+        userauthorization.ldelete   = berecht.pwl
+        userauthorization.lquery    = berecht.pwa
+        userauthorization.lspecial  = berecht.pws
+        userauthorization.lupdate   = berecht.pwm.
+END.

+ 276 - 0
utilities/selectboxHandler.cls

@@ -0,0 +1,276 @@
+ 
+/*------------------------------------------------------------------------
+   File        : queryHandler
+   Purpose     : 
+   Syntax      : 
+   Description : 
+   Author(s)   : walter.riechsteiner
+   Created     : Wed Jul 10 18:09:37 CEST 2024
+   Notes       : 
+ ----------------------------------------------------------------------*/
+
+USING Progress.Json.ObjectModel.JsonObject FROM PROPATH.
+USING OpenEdge.Net.HTTP.IHttpRequest FROM PROPATH.
+USING System.Drawing.CharacterRange FROM ASSEMBLY.
+
+CLASS utilities.selectboxHandler: 
+
+    DEFINE VARIABLE i1 AS INTEGER NO-UNDO.
+    DEFINE VARIABLE i2 AS INTEGER NO-UNDO.
+
+        
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD PUBLIC HANDLE getSelboxCompany( INPUT cFileName AS CHARACTER ):
+        
+        DEFINE VARIABLE cttBufferName AS CHARACTER NO-UNDO.
+        
+        DEFINE VARIABLE httSelect     AS HANDLE    NO-UNDO.
+        DEFINE VARIABLE httBuffer     AS HANDLE    NO-UNDO.
+        
+        cttBufferName = SUBSTITUTE('&1_company', cFileName).
+        
+        CREATE TEMP-TABLE httSelect.
+        httSelect:ADD-NEW-FIELD('value', 'character').
+        httSelect:ADD-NEW-FIELD('label', 'character').
+        httSelect:TEMP-TABLE-PREPARE (cttBufferName).
+        httBuffer = httSelect:DEFAULT-BUFFER-HANDLE.
+
+        FOR EACH companies NO-LOCK 
+            WHERE companies.active :
+            httBuffer:BUFFER-CREATE ().
+            ASSIGN 
+                httBuffer:BUFFER-FIELD('value'):BUFFER-VALUE = companies.company
+                httBuffer:BUFFER-FIELD('label'):BUFFER-VALUE = companies.company_name.
+        END.
+
+        RETURN httBuffer.
+
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD PUBLIC HANDLE getSelboxLanguage( INPUT cFileName AS CHARACTER ):
+        
+        DEFINE VARIABLE cttBufferName AS CHARACTER NO-UNDO.
+        
+        DEFINE VARIABLE httSelect     AS HANDLE    NO-UNDO.
+        DEFINE VARIABLE httBuffer     AS HANDLE    NO-UNDO.
+        
+        cttBufferName = SUBSTITUTE('&1_company', cFileName).
+        
+        CREATE TEMP-TABLE httSelect.
+        httSelect:ADD-NEW-FIELD('value', 'integer'   ).
+        httSelect:ADD-NEW-FIELD('label', 'character' ).
+        httSelect:TEMP-TABLE-PREPARE ('cttBufferName').
+        httBuffer = httSelect:DEFAULT-BUFFER-HANDLE.
+
+        FOR EACH languages NO-LOCK: 
+            httBuffer:BUFFER-CREATE ().
+            ASSIGN 
+                httBuffer:BUFFER-FIELD('value'):BUFFER-VALUE = languages.language_id
+                httBuffer:BUFFER-FIELD('label'):BUFFER-VALUE = languages.language_name.
+        END.
+
+        RETURN httBuffer.
+
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD PUBLIC HANDLE getSelboxTables( INPUT cFileName AS CHARACTER ):
+        
+        DEFINE VARIABLE cttBufferName AS CHARACTER NO-UNDO.
+        
+        DEFINE VARIABLE httSelect     AS HANDLE    NO-UNDO.
+        DEFINE VARIABLE httBuffer     AS HANDLE    NO-UNDO.
+        
+        cttBufferName = SUBSTITUTE('&1_table_name', cFileName).
+
+        CREATE TEMP-TABLE httSelect.
+        httSelect:ADD-NEW-FIELD('value', 'character'   ).
+        httSelect:ADD-NEW-FIELD('label', 'character' ).
+        httSelect:TEMP-TABLE-PREPARE (cttBufferName).
+        httBuffer = httSelect:DEFAULT-BUFFER-HANDLE.
+
+        httBuffer:BUFFER-CREATE ().
+        ASSIGN 
+            httBuffer:BUFFER-FIELD('value'):BUFFER-VALUE = 'table'
+            httBuffer:BUFFER-FIELD('label'):BUFFER-VALUE = 'Default-Value (table)'.
+        FOR EACH Ge_MIS._File NO-LOCK
+            WHERE NOT Ge_MIS._File._File-Name BEGINS '_'
+            AND   NOT Ge_MIS._File._File-Name BEGINS 'SYS': 
+            httBuffer:BUFFER-CREATE ().
+            ASSIGN 
+                httBuffer:BUFFER-FIELD('value'):BUFFER-VALUE = Ge_MIS._File._File-Name
+                httBuffer:BUFFER-FIELD('label'):BUFFER-VALUE = Ge_MIS._File._File-Name.
+        END.
+        FOR EACH FRAMEWORK._File NO-LOCK
+            WHERE NOT FRAMEWORK._File._File-Name BEGINS '_'
+            AND   NOT FRAMEWORK._File._File-Name BEGINS 'SYS': 
+            httBuffer:BUFFER-CREATE ().
+            ASSIGN 
+                httBuffer:BUFFER-FIELD('value'):BUFFER-VALUE = FRAMEWORK._File._File-Name
+                httBuffer:BUFFER-FIELD('label'):BUFFER-VALUE = FRAMEWORK._File._File-Name.
+        END.
+
+        RETURN httBuffer.
+
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD PUBLIC HANDLE getSelboxUsers( INPUT cFileName AS CHARACTER  ):
+        
+        DEFINE VARIABLE cttBufferName AS CHARACTER NO-UNDO.
+        
+        DEFINE VARIABLE httSelect     AS HANDLE    NO-UNDO.
+        DEFINE VARIABLE httBuffer     AS HANDLE    NO-UNDO.
+        
+        cttBufferName = SUBSTITUTE('&1_user_name', cFileName).
+
+        CREATE TEMP-TABLE httSelect.
+        httSelect:ADD-NEW-FIELD('value', 'character'   ).
+        httSelect:ADD-NEW-FIELD('label', 'character' ).
+        httSelect:TEMP-TABLE-PREPARE (cttBufferName).
+        httBuffer = httSelect:DEFAULT-BUFFER-HANDLE.
+        
+        FOR EACH users NO-LOCK: 
+            httBuffer:BUFFER-CREATE ().
+            ASSIGN 
+                httBuffer:BUFFER-FIELD('value'):BUFFER-VALUE = users.user_name
+                httBuffer:BUFFER-FIELD('label'):BUFFER-VALUE = users.display_name.
+        END.
+
+        RETURN httBuffer.
+
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD PUBLIC HANDLE getSelectBoxData(
+        INPUT ipoIdent      AS JsonObject,
+        INPUT ipcFileName   AS CHARACTER,
+        INPUT ipcValueField AS CHARACTER,
+        INPUT ipcLabelField AS CHARACTER 
+        ):
+            
+        DEFINE VARIABLE cttBufferName AS CHARACTER NO-UNDO.
+        
+        DEFINE VARIABLE httSelect     AS HANDLE    NO-UNDO.
+        DEFINE VARIABLE httBuffer     AS HANDLE    NO-UNDO.
+        DEFINE VARIABLE hBuffer       AS HANDLE    NO-UNDO.
+        DEFINE VARIABLE hQuery        AS HANDLE    NO-UNDO.
+        DEFINE VARIABLE hFeld         AS HANDLE    NO-UNDO.
+        DEFINE VARIABLE lcompany      AS LOGICAL   NO-UNDO.
+        DEFINE VARIABLE lactive       AS LOGICAL   NO-UNDO.
+        DEFINE VARIABLE lwhere        AS LOGICAL   NO-UNDO.
+        DEFINE VARIABLE cWhere        AS CHARACTER NO-UNDO.
+        
+        cttBufferName = SUBSTITUTE('&1_&2', ipcFileName, ipcValueField).
+        CREATE BUFFER hBuffer FOR TABLE ipcFileName.
+        MESSAGE cttBufferName.        
+        IF ipcFileName <> 'companies' THEN 
+        DO:
+            hFeld = hBuffer:BUFFER-FIELD('company'):HANDLE NO-ERROR.
+            lcompany = (IF VALID-HANDLE(hFeld) THEN TRUE ELSE FALSE).
+        END.
+        
+        hFeld = hBuffer:BUFFER-FIELD('active'):HANDLE NO-ERROR.
+        lactive  = (IF VALID-HANDLE(hFeld) THEN TRUE ELSE FALSE).
+        
+        CREATE TEMP-TABLE httSelect.
+        httSelect:ADD-NEW-FIELD('value', 'character').
+        httSelect:ADD-NEW-FIELD('label', 'character').
+        httSelect:TEMP-TABLE-PREPARE (cttBufferName).
+        httBuffer = httSelect:DEFAULT-BUFFER-HANDLE.
+        MESSAGE 'lcompany = ' lcompany  ' lactive = ' lactive.        
+        lWhere = (IF lcompany OR lactive THEN TRUE ELSE FALSE).
+        cWhere = SUBSTITUTE('FOR EACH &1 NO-LOCK ', ipcFileName).
+        IF lcompany THEN 
+        DO:
+            cWhere = cWhere + SUBSTITUTE('&1 &2.company = &3 ', (IF lWhere THEN 'WHERE' ELSE 'AND'), ipcFileName, QUOTER(ipoIdent:getCharacter('company'))).
+            lwhere = FALSE.
+        END.
+        IF lactive  THEN 
+        DO:
+            cWhere = cWhere + SUBSTITUTE('&1 &2.active  = &3 ', (IF lWhere THEN 'WHERE' ELSE 'AND'), ipcFileName, TRUE                            ).
+            lwhere = FALSE.
+        END.
+        MESSAGE cWhere.
+        
+        CREATE QUERY hQuery.
+        hQuery:SET-BUFFERS(hBuffer).
+        hQuery:QUERY-PREPARE (cWhere).
+        hQuery:QUERY-OPEN().
+        hQuery:GET-FIRST ().
+        DO WHILE NOT hQuery:QUERY-OFF-END:
+            httBuffer:BUFFER-CREATE ().
+            ASSIGN 
+                httBuffer:BUFFER-FIELD('value'):BUFFER-VALUE = hBuffer:BUFFER-FIELD(ipcValueField):BUFFER-VALUE
+                httBuffer:BUFFER-FIELD('label'):BUFFER-VALUE = hBuffer:BUFFER-FIELD(ipcLabelField):BUFFER-VALUE.
+            hQuery:GET-NEXT ().
+        END.
+
+        // httBuffer:WRITE-JSON('FILE', 'C:\TEMP\httBuffer.json', TRUE).
+
+        RETURN httBuffer.
+
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    METHOD PUBLIC HANDLE getUserRoleSelect(
+        INPUT  ipccompany AS CHARACTER
+        ):
+        
+        DEFINE VARIABLE httBuffer AS HANDLE NO-UNDO.
+
+        CREATE BUFFER httBuffer.
+        httBuffer:ADD-NEW-FIELD ('value', 'CHARACTER').
+        httBuffer:ADD-NEW-FIELD ('label', 'CHARACTER').
+        httBuffer:TEMP-TABLE-PREPARE ('users_role').
+        
+        httBuffer:BUFFER-CREATE().
+        ASSIGN 
+            httBuffer:BUFFER-FIELD('value'):buffer-value = 'admin'
+            httBuffer:BUFFER-FIELD('label'):buffer-value = 'admin'.        
+        httBuffer:BUFFER-CREATE().
+        ASSIGN 
+            httBuffer:BUFFER-FIELD('value'):buffer-value = 'user'
+            httBuffer:BUFFER-FIELD('label'):buffer-value = 'Benutzer'.        
+        
+        RETURN httBuffer.
+
+    END METHOD.
+
+    /*------------------------------------------------------------------------------
+     Purpose:
+     Notes:
+    ------------------------------------------------------------------------------*/
+
+    DESTRUCTOR PUBLIC selectboxHandler ( ):
+        MESSAGE 'Destructor selectboxHandler '.
+    /*        DELETE OBJECT hQuery NO-ERROR.    */
+    /*        DELETE OBJECT hBuffer NO-ERROR.   */
+    END DESTRUCTOR.
+
+END CLASS.

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 467 - 271
utilities/utilitiesHandler.cls


+ 45 - 0
webmenu.d

@@ -0,0 +1,45 @@
+"1000" "Admin" 10 0 0 "Stammdaten" "" "" 2025-11-13T22:39:09.008 2025-11-13T22:39:09.008 no "simple"
+"1000" "Admin" 10 10 0 "Adressverwaltung" "" "" 2025-11-13T22:39:09.008 2025-11-13T22:39:09.008 no "simple"
+"1000" "Admin" 10 10 10 "Adressen" "adressen" "" 2025-11-13T22:39:09.008 2025-11-13T22:39:09.008 no "simple"
+"1000" "Admin" 100 0 0 "Tabellen" "" "" 2025-11-13T22:39:09.008 2025-11-13T22:39:09.008 no "simple"
+"1000" "Admin" 100 10 0 "Adresstabellen" "" "" 2025-11-13T22:39:09.008 2025-11-13T22:39:09.008 no "simple"
+"1000" "Admin" 100 10 10 "Adressarten" "adressarten" "" 2025-11-13T22:39:09.009 2025-11-13T22:39:09.009 no "simple"
+"1000" "Admin" 100 10 20 "Sprachen" "sprachen" "" 2025-11-13T22:39:09.009 2025-11-13T22:39:09.009 no "simple"
+"1000" "mo" 10 0 0 "Stammdaten" "" "" 2025-11-12T16:21:31.671 2025-11-12T16:21:31.671 no "simple"
+"1000" "mo" 10 10 0 "Adressverwaltung" "" "" 2025-11-12T16:21:31.672 2025-11-12T16:21:31.672 no "simple"
+"1000" "mo" 10 10 10 "Adressen" "adressen" "" 2025-11-12T16:21:31.672 2025-11-12T16:21:31.672 no "simple"
+"1000" "mo" 100 0 0 "Tabellen" "" "" 2025-11-12T16:21:31.671 2025-11-12T16:21:31.671 no "simple"
+"1000" "mo" 100 10 0 "Adresstabellen" "" "" 2025-11-12T16:21:31.672 2025-11-12T16:21:31.672 no "simple"
+"1000" "mo" 100 10 10 "Adressarten" "adressarten" "" 2025-11-12T16:21:31.673 2025-11-12T16:21:31.673 no "simple"
+"1000" "mo" 100 10 20 "Sprachen" "sprachen" "" 2025-11-12T16:21:31.673 2025-11-12T16:21:31.673 no "simple"
+"1000" "mo" 900 0 0 "Administration" "" "" 2025-11-12T16:21:31.672 2025-11-12T16:21:31.672 no "simple"
+"1000" "mo" 900 10 0 "Benutzerverwaltung" "" "" 2025-11-12T16:21:31.672 2025-11-12T16:21:31.672 yes "simple"
+"1000" "mo" 900 10 10 "Benutzer" "users" "" 2025-11-12T16:21:31.673 2025-11-12T16:21:31.673 no "new"
+"1000" "mo" 900 10 20 "Berechtigungen" "authorization" "" 2025-11-12T16:21:31.673 2025-11-12T16:21:31.673 no "new"
+"1000" "mo" 900 20 0 "Menudesigner" "menudesigner" "" 2025-11-12T16:21:31.672 2025-11-12T16:21:31.672 yes "simple"
+"1000" "mo" 900 30 0 "Formdesigner" "formdesigner" "" 2025-11-12T16:21:31.672 2025-11-12T16:21:31.672 yes "simple"
+"1000" "wari" 10 0 0 "Stammdaten" "" "" 2025-11-12T17:34:22.346 2025-11-12T17:34:22.346 no "simple"
+"1000" "wari" 10 10 0 "Adressverwaltung" "" "" 2025-11-12T17:34:22.347 2025-11-12T17:34:22.347 no "simple"
+"1000" "wari" 10 10 10 "Adressen" "adressen" "" 2025-11-12T17:34:22.347 2025-11-12T17:34:22.347 no "simple"
+"1000" "wari" 100 0 0 "Tabellen" "" "" 2025-11-12T17:34:22.346 2025-11-12T17:34:22.346 no "simple"
+"1000" "wari" 100 10 0 "Adresstabellen" "" "" 2025-11-12T17:34:22.347 2025-11-12T17:34:22.347 no "simple"
+"1000" "wari" 100 10 10 "Adressarten" "adressarten" "" 2025-11-12T17:34:22.348 2025-11-12T17:34:22.348 no "simple"
+"1000" "wari" 100 10 20 "Sprachen" "sprachen" "" 2025-11-12T17:34:22.348 2025-11-12T17:34:22.348 no "simple"
+"1000" "wari" 900 0 0 "Administration" "" "" 2025-11-12T17:34:22.347 2025-11-12T17:34:22.347 no "simple"
+"1000" "wari" 900 10 0 "Benutzerverwaltung" "" "" 2025-11-12T17:34:22.347 2025-11-12T17:34:22.347 yes "simple"
+"1000" "wari" 900 10 10 "Benutzer" "users" "" 2025-11-12T17:34:22.348 2025-11-12T17:34:22.348 no "new"
+"1000" "wari" 900 10 20 "Berechtigungen" "authorization" "" 2025-11-12T17:34:22.348 2025-11-12T17:34:22.348 no "new"
+"1000" "wari" 900 20 0 "Menudesigner" "menudesigner" "" 2025-11-12T17:34:22.347 2025-11-12T17:34:22.347 yes "simple"
+"1000" "wari" 900 30 0 "Formdesigner" "formdesigner" "" 2025-11-12T17:34:22.347 2025-11-12T17:34:22.347 yes "new"
+.
+PSC
+filename=webmenu
+records=0000000000033
+ldbname=Ge_MIS
+timestamp=2025/11/13-23:12:41
+numformat=44,46
+dateformat=dmy-1950
+map=NO-MAP
+cpstream=utf-8
+.
+0000003586

Vissa filer visades inte eftersom för många filer har ändrats