From 5644899cb1665b88797b51424e102e363626a838 Mon Sep 17 00:00:00 2001
From: "S.Listl" <S.Listl@SLISTL.aditosoftware.local>
Date: Fri, 27 Mar 2020 16:34:08 +0100
Subject: [PATCH] 1049530 - HasLinkedObjectTester implemented

---
 process/Employee_lib/process.js |  12 +++
 process/Entity_lib/process.js   | 144 +++++++++++++++++++++++++++++++-
 2 files changed, 155 insertions(+), 1 deletion(-)

diff --git a/process/Employee_lib/process.js b/process/Employee_lib/process.js
index 94f25b38ba0..edca392f0cd 100644
--- a/process/Employee_lib/process.js
+++ b/process/Employee_lib/process.js
@@ -129,4 +129,16 @@ EmployeeUtils.hasRelations = function (pContactId)
         {
             return pSelect.cell() != "";
         });
+}
+
+/**
+ * checks if a user with the given contactId exists
+ * 
+ * @param {String} pContactId the contactId the user has to have
+ * @return {Boolean} wheter the user exists or not
+ */
+EmployeeUtils.isUser = function (pContactId)
+{
+    var user = tools.getUserByAttribute(tools.CONTACTID, pContactId);
+    return user != null;
 }
\ No newline at end of file
diff --git a/process/Entity_lib/process.js b/process/Entity_lib/process.js
index 15acae96dcb..ada186ee668 100644
--- a/process/Entity_lib/process.js
+++ b/process/Entity_lib/process.js
@@ -1,3 +1,4 @@
+import("system.entities");
 import("system.result");
 import("system.neon");
 import("system.vars");
@@ -173,4 +174,145 @@ FieldChanges._getStorage = function()
 FieldChanges._setStorage = function(pAllChanges)
 {
     return vars.set("$context.FieldChanges", pAllChanges);
-};
\ No newline at end of file
+};
+
+
+/**
+ * Object for testing if linked datasets exists.
+ * 
+ * @param {String[]} pConsumers names of the consumers to be tested
+ */
+function HasLinkedObjectTester (pConsumers)
+{
+    //This array will contain objects that are used for the validation. You can put any object in this array as long as it provides
+    //a method 'checkForObjects' that can be invoked.
+    this._validationObjects = [];
+
+    if (pConsumers)
+        pConsumers.forEach(this.andNoConsumerRows, this);
+
+    Object.defineProperty(this, "length", {
+        get : function () {return this._validationObjects.length;}
+    });
+}
+
+/**
+ * @ignore
+ */
+HasLinkedObjectTester._testForEntity = function ()
+{
+    entities.createConfigForLoadingConsumerRows()
+    var loadConfig = entities.createConfigForLoadingRows()
+        .entity(this.entity)
+        .provider(this.provider)
+        .ignorePermissions(true);
+
+    if (this.parameters)
+    {
+        for (let param in this.parameters)
+            loadConfig.addParameter(param, this.parameters[param]);
+    }
+    return entities.getRowCount(loadConfig) == 0;
+}
+
+/**
+ * @ignore
+ */
+HasLinkedObjectTester._testForConsumer = function ()
+{
+    //TODO: implement when possible
+    return false;
+}
+
+/**
+ * @ignore
+ */
+HasLinkedObjectTester._testForCallback = function ()
+{
+    fnResult = this.callbackFn();
+    return this.failValue
+        ? fnResult != this.failValue
+        : fnResult;
+}
+
+/**
+ * !!! YOU CAN'T USE THIS FUNCTION YET !!!
+ * 
+ * Adds a consumer to test for rows to the object.
+ * 
+ * @ignore
+ * 
+ * @param {String} pConsumer name of the consumer
+ * @return {HasLinkedObjectTester} current object
+ */
+HasLinkedObjectTester.prototype.andNoConsumerRows = function (pConsumer)
+{
+    throw new Error("HasLinkedObjectTester.prototype.andNoConsumerRows does not work yet")
+    this._validationObjects.push({
+        checkForObjects : HasLinkedObjectTester._testForConsumer,
+        consumer : pConsumer
+    });
+    return this;
+}
+
+/**
+ * Adds a entity with provider to test for rows. You have to set the parameters by yourself.
+ * 
+ * @param {String} pEntity name of the entity
+ * @param {String} pProvider provider that should be used
+ * @param {Object} [pParameters] parameters to set
+ * @return {HasLinkedObjectTester} current object
+ * @example
+ *  new HasLinkedObjectTester()
+ *      .andNoEntityRows("Activity_entity", "LinkedObjects", {ObjectId_param : currentContext, RowId_param : contactId})
+ */
+HasLinkedObjectTester.prototype.andNoEntityRows = function (pEntity, pProvider, pParameters)
+{
+    this._validationObjects.push({
+        checkForObjects : HasLinkedObjectTester._testForEntity,
+        entity : pEntity,
+        provider : pProvider,
+        parameters : pParameters
+    });
+    return this;
+}
+
+/**
+ * Adds a custom callback function that tests for linked objects.
+ * 
+ * @param {String} pCallbackFn validation function, it should return true if NO linked objects were found, but the expected value can be changed
+ *                             by providing an own 'pFailValue'
+ * @param {Object} [pFailValue=false] if the given function returns this value, the ovarall validation will fail and return false
+ * @return {HasLinkedObjectTester} current object
+ */
+HasLinkedObjectTester.prototype.and = function (pCallbackFn, pFailValue)
+{
+    this._validationObjects.push({
+        checkForObjects : HasLinkedObjectTester._testForCallback,
+        callbackFn : pCallbackFn,
+        failValue : pFailValue
+    });
+    return this;
+}
+
+/**
+ * Executes the validation of all tests that have been added to the object. If every test returns true, the result will also be true,
+ * but if any test returns false, the execution will stop and false is returned.
+ * 
+ * @return {Boolean} true, if NO linked objects were found
+ */
+HasLinkedObjectTester.prototype.validate = function ()
+{
+    return this._validationObjects.every(function (duck)
+    {
+        return duck.checkForObjects();
+    });
+}
+
+/**
+ * @return {String} validation result as String, so that .validate() does not always have to be called explicitly
+ */
+HasLinkedObjectTester.prototype.toString = function ()
+{
+    return String(this.validate());
+}
-- 
GitLab