Skip to content
Snippets Groups Projects
process.js 16.70 KiB
import("system.tools");
import("system.text");
import("system.datetime");
import("system.notification");
import("system.translate");
import("Contact_lib");
import("KeywordRegistry_basic");
import("system.vars");
import("system.util");
import("Sql_lib");
import("Util_lib");
import("system.db");
import("system.indexsearch");
import("JditoFilter_lib");
import("Util_lib");
import("system.process");
import("Employee_lib");

/**
 * Functions for district.
 */
function DistrictUtils () {}

/**
 * Gets the name of a district
 * 
 * @param {String} pDistrictId                  <p>
 *                                              Id of the district.<br>
 * @return {String}                             <p>
 *                                              Name of the district.<br>
 */
DistrictUtils.getDistrictName = function (pDistrictId)
{
    var districtName = newSelect("DISTRICT_NAME")
                            .from("DISTRICT")
                            .where("DISTRICT.DISTRICTID", pDistrictId)
                            .cell(true);    
                            
    return(districtName)
}

/**
 * Get data from district
 * 
 * @param {String} pDistrictId                  <p>
 *                                              ID of a district<br>
 * @return {Array}                              <p>
 *                                              array of data from a district <br>
 */
DistrictUtils.getDataFromDistrict = function (pDistrictId)
{    
    var districtData = newSelect("DISTRICT_FILTER, PARENTDISTRICT_DISTRICTID")
                            .from("DISTRICT")
                            .where("DISTRICT.DISTRICTID", pDistrictId)
                            .arrayRow();                   
    return(districtData);
}


/**
 * Get data from a special district
 * 
 * @param {String} pDistrictContactId           <p>
 *                                              Id of the districtcontact.<br>
 * @return {Array}                              <p>
 *                                              array of data from one districtcontact dataset <br>
 */
DistrictUtils.getDataFromDistrictContact = function (pDistrictContactId)
{
    var arrData = newSelect("DISTRICT_ID, ADVISER_CONTACT_ID, CONTACT_ID")
                            .from("DISTRICTCONTACT")
                            .where("DISTRICTCONTACT.DISTRICTCONTACTID", pDistrictContactId)
                            .arrayRow();    
                            
    return(arrData);
}


/**
 * Executes a process to assign districts on the server and creates a notification when finished.
 * 
 * @param {Array} pArrDistrictIds                   <p>
 *                                                  Array of district-IDs.<br>
 * @param {String} pUser=currentUser (optional)     <p>
 *                                                  User who will get the notification, <br>
 *                                                  User who will start the batch job <br>
 * @param {String} pContactId (optional)            <p>   
 *                                                  Organisation which should be assigned to all  <br>
 *                                                  according districts with auto assignment is true  <br>                                            
 */
DistrictUtils.assignDistrictOnServer = function (pArrDistrictIds, pUser, pContactId)
{
    //pUser hat folgendes Format: _____USER_bcdfb521-c7d0-4ef1-8916-78e7d3232046
    if (pUser === undefined)
        pUser = EmployeeUtils.getCurrentUserId(); 
    var processConfig = process.createStartAsyncConfig()
        .setName("assignDistrict_serverProcess")
        .setLocalVariables({
            arrDistrictIds : pArrDistrictIds.join(";"),
            user : pUser || "", 
            contactId : pContactId || ""
        })
        .setUser(pUser);
    process.startAsync(processConfig);
}

/**
 * Assignes a district to companies. You should only call this function on the server because it
 * can take some time to execute, use DistrictUtils.assignDistrictOnServer instead.
 * 
 * @param {String} pDistrictId                  <p>
 *                                              Id of the district.<br>
 * @param {String} pAppliedFilter               <p>
 *                                              Filter condition to get the assigned companies.<br>
 * @param {String} pContactId (opt)             <p>
 *                                              Only filled when a special contact-ID should assigned to a district.<br>*                                              
 * @return {Object}                             <p>
 *                                              Count of new assigned companies and no longer assigned companies.<br>
 */
DistrictUtils.assignDistrict = function (pDistrictId, pAppliedFilter, pContactId)
{    
    if (pContactId == undefined)
        pContactId = null;
    
    var newAssigned = 0;
    var unchanged = 0;
    var invalid = 0;
    
    //Einlesen von allen bereits existierenden automatischen Zuordnungen,
    //die nicht auf Status 'zur Prüfung' stehen
    //Nur notwendig, wenn pContactId leer ist. Ansonsten soll ja gezielt ein neuer Datensatz angelegt werden
    var arrExistingIds = [];
    if (!pContactId)
    {
        arrExistingIds = new SqlBuilder()
                .select("DISTRICTCONTACT.DISTRICTCONTACTID, DISTRICTCONTACT.CONTACT_ID, DISTRICTCONTACT.ADVISER_CONTACT_ID")
                .from("DISTRICTCONTACT")    
                .where("DISTRICTCONTACT.DISTRICT_ID", pDistrictId)
                .and ("DISTRICTCONTACT.ORIGIN", $KeywordRegistry.districtOrigin$auto())
                .and ("DISTRICTCONTACT.STATUS", $KeywordRegistry.contactStatus$inReview(), SqlBuilder.NOT_EQUAL())
                .table();    
    }
    
    //Einlesen aller Betreuer, die dem übergebenen Gebiet zugeordnet sind
    var arrResponsibleIds = new SqlBuilder()
            .select("DISTRICTRESPONSIBLE.EMPLOYEE_CONTACT_ID, DISTRICTRESPONSIBLE.ADVISER_ROLE, " +
                    "DISTRICTRESPONSIBLE.ADVISER_STATUS, DISTRICTRESPONSIBLE.VALID_FROM, DISTRICTRESPONSIBLE.VALID_UNTIL, DISTRICTRESPONSIBLE.VISITFREQUENCY")
            .from("DISTRICTRESPONSIBLE")    
            .where("DISTRICTRESPONSIBLE.DISTRICT_ID", pDistrictId)
            .table();

    //Aufbereiten des im JSON-Format übergebenen Filters in eine SQL-Condition
    var appliedFilterCondition = JSON.parse(pAppliedFilter).filter;
    appliedFilterCondition = JSON.stringify(appliedFilterCondition);   
    var sqlCondition = db.toFilterCondition(appliedFilterCondition, "Organisation_entity");       
    
    //Einlesen der Contact-IDs zu den Firmen, die gemäß Filter diesem Gebiet zugeordnet sind
    var arrOrgContactIds = new SqlBuilder()
            .selectDistinct("CONTACT.CONTACTID")
            .from("ORGANISATION")
            .join("CONTACT", newWhere("ORGANISATION.ORGANISATIONID = CONTACT.ORGANISATION_ID").and("CONTACT.PERSON_ID is null"))
            .leftJoin("ADDRESS", "ADDRESS.ADDRESSID = CONTACT.ADDRESS_ID")
            .leftJoin("CLASSIFICATIONSTORAGE", "CLASSIFICATIONSTORAGE.OBJECT_ROWID = CONTACT.CONTACTID")
            .whereIfSet(sqlCondition)
            .andIfSet("CONTACT.CONTACTID", pContactId)
            .arrayColumn();               
                 
    var insertArray = [];
    var colsInsert = [
            "DISTRICTCONTACTID",
            "CONTACT_ID",
            "DISTRICT_ID",
            "ADVISER_CONTACT_ID",
            "ADVISER_ROLE",
            "STATUS",
            "VALID_FROM", 
            "VALID_UNTIL",
            "ORIGIN",
            "USER_NEW",
            "DATE_NEW",
            "VISITFREQUENCY"
        ];
    var updateArray = [];
    var colsUpdate = [
            "STATUS",
            "USER_EDIT",
            "DATE_EDIT"
        ];        

    //Anlegen der Firmen-Betreuer-Datensätze in der Tabelle DISTRICTCONTACT
    for (var i=0; i<arrOrgContactIds.length; i++)
    {
        for (var j=0; j<arrResponsibleIds.length; j++)
        {
            //Existiert der Firmen-Betreuer-Datensatz bereits?
            var found = 'N';
            for (var k=0; k<arrExistingIds.length; k++)
            {
                if (arrExistingIds[k][1] == arrOrgContactIds[i] && arrExistingIds[k][2] == arrResponsibleIds[j][0])
                {
                    unchanged++;
                    found = 'Y';
                    //Gefundenen Eintrag aus dem Array entfernen 
                    //-> Am Schluss bleiben in dem Array alle ungültigen Datensätze übrig. Bei diesen wird weiter unten der Status geändert 
                    arrExistingIds.splice(k, 1);
                    break;
                }
            }
            //Firmen-Betreuer-Datensatz existiert noch nicht -> Insert
            if (found == 'N')
            {
                //Falls Status null, dann auf active setzen
                if (Utils.isNullOrEmpty(arrResponsibleIds[j][2])) 
                {
                    arrResponsibleIds[j][2] = $KeywordRegistry.contactStatus$active();
                }

                var valsInsert = [
                    util.getNewUUID(),
                    arrOrgContactIds[i],
                    pDistrictId,
                    arrResponsibleIds[j][0],
                    arrResponsibleIds[j][1],
                    arrResponsibleIds[j][2],
                    arrResponsibleIds[j][3],
                    arrResponsibleIds[j][4],
                    $KeywordRegistry.districtOrigin$auto(),
                    vars.get("$sys.user"),
                    vars.get("$sys.date"),
                    arrResponsibleIds[j][5]
                ]; 
                insertArray.push(["DISTRICTCONTACT", colsInsert, null, valsInsert]);
            }            
        }        
    }
    newAssigned = insertArray.length;
    db.inserts(insertArray);    
    
    //Gibt es noch ungültige Zuordnungen, dann bei diesen den Status auf "zur Prüfung setzen"
    if (arrExistingIds.length > 0)
    {
        invalid = arrExistingIds.length;
                                
        //die erste Spalte enthält die Ids der zu aktualisierenden Datensätze
        var arrIds = arrExistingIds.map(function(value) { return value[0]; });
        DistrictUtils.setDistrictContactStatus (arrIds, $KeywordRegistry.contactStatus$inReview());
    }
        
    return {
        newAssigned : newAssigned,
        invalid : invalid,
        unchanged : unchanged
    };    
}


/**
 * Get the complete hierarchical filter
 * 
 * @param {JSON-String} pDistrictFilter         <p>
 *                                              The filter of the current level<br>
 * @param {String} pParentDistrict_DistrictId   <p>
 *                                              District-ID of the parent district<br>*                                              
 * @return {JSON-String}                        <p>
 *                                              JSON-String of the complete filter (all levels) <br>
 */
DistrictUtils.getAppliedFilter = function (pDistrictFilter, pParentDistrict_DistrictId)
{
    var parentFilter = DistrictUtils.getParentFilter(pParentDistrict_DistrictId);

    var appliedFilter = {
        entity: "Organisation_entity", 
        filter: {
            type: "group", 
            operator: "AND", 
            childs: []
        }
    };

    if (parentFilter)
    {
        appliedFilter.filter.childs.push(JSON.parse(parentFilter).filter);
    }
    if (pDistrictFilter)
    {
        appliedFilter.filter.childs.push(JSON.parse(pDistrictFilter).filter);
    }

    return JSON.stringify(appliedFilter);
}

/**
 * Get the filter starting with the parent level
 * @param {String} pParentDistrict_DistrictId   <p>
 *                                              District-ID of the parent district<br>                                              
 * @return {JSON-String}                        <p>
 *                                              JSON-String of the filter starting with the parent<br>
 */
DistrictUtils.getParentFilter = function (pParentDistrict_DistrictId)
{
    var res = "";

    if (pParentDistrict_DistrictId)
    {
        var completeParentFilter = DistrictUtils._getParentFilter(pParentDistrict_DistrictId, null);
        completeParentFilter.entity = "Organisation_entity";
        res = completeParentFilter;
    }
    else
    {
        var entity = "Organisation_entity";
        var emptyFilter = {
            entity: entity, 
            filter: {
                type: "group", 
                operator: "AND", 
                childs: []
            }
        };

        res = emptyFilter;
    }

    return JSON.stringify(res);    
}

/**
 * This function will recursively go through each filter level up to the root.
 * @param {String} pParentDistrict_DistrictId   <p>
 *                                              District-ID of the parent district<br> 
 * @param {JSON} pPreviousFilter                <p>
 *                                              Collected filters so far<br>                                                                                    
 * @return {JSON}                               <p>
 *                                              JSON-Object of the collected filters<br>
 */
DistrictUtils._getParentFilter = function (pParentDistrict_DistrictId, pPreviousFilter)
{
    var resFilter;
    
    if (pPreviousFilter != null)
    {
        resFilter = pPreviousFilter;
    } 

    if (pParentDistrict_DistrictId)
    {
        var parentDistrictFilter, grandParentDistrict;
        [parentDistrictFilter, grandParentDistrict] = newSelect(["DISTRICT.DISTRICT_FILTER", "DISTRICT.PARENTDISTRICT_DISTRICTID"])
                                                            .from("DISTRICT")
                                                            .where("DISTRICT.DISTRICTID", pParentDistrict_DistrictId)
                                                            .arrayRow();

        parentDistrictFilter = JSON.parse(parentDistrictFilter);

        if (pPreviousFilter)
            parentDistrictFilter.filter.childs.push(resFilter.filter);
        
        resFilter = parentDistrictFilter;

        if (grandParentDistrict.length > 0)
        {   
            resFilter = DistrictUtils._getParentFilter(grandParentDistrict, resFilter);
        }
    }

    return resFilter;
}


/**
 * This function will set the status of districtcontact datasets
 * @param {Array} pArrIds                       <p>
 *                                              IDs of districtcontact<br> 
 * @param {String} pStatus                      <p>
 *                                              Status, for example $KeywordRegistry.contactStatus$active<br>                                                                                    
 * @return {none}                               <p>
 */
DistrictUtils.setDistrictContactStatus = function (pArrIds, pStatus)
{
    var updateArray = [];
    var colsUpdate = [
            "STATUS",
            "USER_EDIT",
            "DATE_EDIT"
        ]; 
    var valsUpdate = [
        pStatus,
        vars.get("$sys.user"),
        vars.get("$sys.date")
        ];          
        
    for (var i=0; i<pArrIds.length; i++)
    {          
        var condition = newWhere("DISTRICTCONTACT.DISTRICTCONTACTID", pArrIds[i]);
        updateArray.push(["DISTRICTCONTACT", colsUpdate, null, valsUpdate, condition.build()]);        
    }
    db.updates(updateArray);
}


/**
 * This function will notificate the district contact that he/she was assigned
 * 
 * @param {String} pDistrictContactId           <p>
 *                                              DistrictContact-ID of the new Dataset<br>                                                                                   
 * @return <none>                               <p>
 */
DistrictUtils.notificateNewDistrictContact = function(pDistrictContactId){
    message = translate.text("Assignment to a new district/company!");

    //[0]: DISTRICT_ID, [1]: ADVISER_CONTACT_ID, [2]: CONTACT_ID
    var arrayDistrictContact = DistrictUtils.getDataFromDistrictContact(pDistrictContactId);
    //get corresponding profile information of the systemalias
    var user = tools.getUserByAttribute(tools.CONTACTID, arrayDistrictContact[1], tools.PROFILE_DEFAULT);
    
    //You can only send a notification, if the user is an employee
    if (user)
    {
        var userName = user[tools.NAME];
        var districtName = DistrictUtils.getDistrictName(arrayDistrictContact[0]);
        var organisationName = ContactUtils.getFullTitleByContactId(arrayDistrictContact[2]);
        // Benachrichtigung am Ende der Zuordnungen     
        description = translate.withArguments("You were assigned as new district contact to district %0 and organisation %1.",
            [districtName, organisationName]);
        notification.addNotification(util.getNewUUID(), text.encodeMS(["Organisation", arrayDistrictContact[2]]), null, null, "DistrictAssigned", notification.PRIO_NORMAL, 2, notification.STATE_UNSEEN, [userName], message, description);    
    }
}