Skip to content
Snippets Groups Projects
process.js 9.87 KiB
import("system.logging");
import("system.db");
import("Keyword_lib");
import("KeywordRegistry_basic");
import("Contact_lib");
import("Communication_lib");

function StandardObject (pObjectType, pObjectID, pScopeType, pScopeID) {
    if (!this._isValidType("object", pObjectType))
        throw new Error("StandardObject: Invalid object type")
    if (!this._isValidType("scope", pScopeType))
        throw new Error("StandardObject: Invalid scope type")
    
    this.objectType = pObjectType
    this.objectID = pObjectID
    this.scopeType = pScopeType
    this.scopeID = pScopeID
}

StandardObject.CONST_OBJECT_ADDRESS = function () {
    return "Address"
}

StandardObject.CONST_OBJECT_COMMUNICATION = function () {
    return "Communication"
}

StandardObject.CONST_SCOPE_PERSON = function () {
    return "Person"
}

StandardObject.CONST_SCOPE_ORGANISATION = function () {
    return "Organisation"
}

StandardObject.prototype._isValidType = function (pFor, pType) {
    var validObjectTypes = ["Address", "Communication"]
    var validScopeTypes = ["Person", "Organisation"]
    if (pFor === "object") {
        return validObjectTypes.indexOf(pType) !== -1
    } else if (pFor === "scope"){
        return validScopeTypes.indexOf(pType) !== -1
    } else {
        return false;
    }
}

/**
 * Asserts the object type of this instance against the
 * given type.
 * 
 * @throws Error if assertion fails.
 */
StandardObject.prototype._assertObjectType = function (pType) {
    if (this.objectType !== pType)
        throw new Error("Object assertion: Invalid type");
}

/**
 * Asserts the scope type of this instance against the
 * given type.
 * 
 * @throws Error if assertion fails.
 */
StandardObject.prototype._assertScopeType = function (pType) {
    if (this.scopeType !== pType)
        throw new Error("Scope assertion: Invalid type");
}

/**
 * Asserts that the object ID is NOT null.
 * 
 * @throws Error if assertion fails.
 */
StandardObject.prototype._assertObjectIdNotNull = function () {
    if (this.objectID === null)
        throw new Error("Object assertion: ID is null");
}

/**
 * Asserts that the scope ID is NOT null.
 * 
 * @throws Error if assertion fails.
 */
StandardObject.prototype._assertScopeIdNotNull = function () {
    if (this.scopeID === null)
        throw new Error("Scope assertion: ID is null");
}

/**
 * Shall be executed in the `valueProcess` of the `ADDRESS_ID` in the
 * `Person` entity. This function will take care about the standard address
 * of the linked organisation.o
 * 
 * @param pSelectedOrganisationID The ID of the currently selected organisation.
 * @return Standard address to apply to the field or null
 * (if no standard address was found)
 */
StandardObject.prototype.onPersonValueChange = function (pSelectedOrganisationID) {
    this._assertScopeIdNotNull();
    
    // Check if the organisation has an standard address
    var addressID = this._getCompanyStandardAddress(pSelectedOrganisationID);
    
    return addressID;
}

/**
 * Shall be executed on the `onDBInsert` process of the recordContainer
 * of the object type (Address or Communication). This algorithm works
 * on a "random" basis: Which object gets first inserted will get the
 * place as standard.
 */
StandardObject.prototype.onObjectInsert = function () {
    this._assertObjectIdNotNull();
    this._assertScopeIdNotNull(); 
    
    if (this.objectType === StandardObject.CONST_OBJECT_ADDRESS()) {
        this._onAddressInsert();
    } else if (this.objectType === StandardObject.CONST_OBJECT_COMMUNICATION) {
        this._onCommunicationInsert();
    }
}

/**
 * Shall be execute only on the `onDBInsert` process of the recordContainer
 * of the `Address` entity. This will set the standard address on the
 * contact if it's currently null.
 */
StandardObject.prototype._onAddressInsert = function () {
    // Assert
    this._assertObjectType(StandardObject.CONST_OBJECT_ADDRESS());
    
    if (!this._hasContactStandardAddress(this.scopeID)) {
        this._setContactStandardAddress(this.objectID, this.scopeID);
    }
}

StandardObject.prototype.onPersonUpdate = function (pOrganisationID) {
    // Assert
    this._assertScopeType(StandardObject.CONST_SCOPE_PERSON());
    
    var isOrganisationAddress = this._isOrganisationAddress(this.scopeID);
    
    if (isOrganisationAddress) {
        // Update to new address of org
        var addressID = this._getCompanyStandardAddress(pOrganisationID);
        
        this._setContactStandardAddress(addressID, this.scopeID);
    }
}

StandardObject.prototype.onCommunicationInsert = function (pMediumID) {
    // Assert
    this._assertObjectType(StandardObject.CONST_OBJECT_COMMUNICATION());
    this._assertObjectIdNotNull();
    this._assertScopeIdNotNull();
    
    var mediumCategory = this._getMediumCategory(pMediumID);
    
    var hasStandard = this._hasStandardCommunicationByMedium(this.scopeID, mediumCategory);
    if (!hasStandard) {
        this._setStandardCommunication(this.objectID, 1);
    }
}

StandardObject.prototype.onCommunicationUpdate = function (pMediumID) {
    // Assert
    this._assertObjectType(StandardObject.CONST_OBJECT_COMMUNICATION());
    this._assertObjectIdNotNull();
    this._assertScopeIdNotNull();
    
    this._setStandardCommunication(this.objectID, 0);
    
    var mediumCategory = this._getMediumCategory(pMediumID);
    
    var contactID = this._getContactIdByCommunication(this.objectID);
    
    var hasStandard = this._hasStandardCommunicationByMedium(contactID, mediumCategory);
    if (!hasStandard)
        this._setStandardCommunication(this.objectID, 1);
}

/**
 * Checks if the given contact ID has any address ID set. If there is a standard
 * address it will return `true`, otherwise `false`. This function asserts that
 * it's currently working on a `Address` object.
 * 
 * @param pContactID Contact ID to check.
 * @return If the contact ID has standard address.
 */
StandardObject.prototype._hasContactStandardAddress = function (pContactID) {
    this._assertObjectType(StandardObject.CONST_OBJECT_ADDRESS());
    
    var databaseResult = db.cell("select ADDRESS_ID from CONTACT"
        + " where CONTACTID = '" + pContactID + "'");
    
    return databaseResult !== "";
}

/**
 * Will set the given address ID on the given contact ID. This function asserts
 * that it's currently working on an `Address` object.
 * 
 * @param pAddressID New address ID to set on the contact.
 * @param pContactID The contact ID to set the address ID on. 
 */
StandardObject.prototype._setContactStandardAddress = function (pAddressID, pContactID) {
    // Assert.
    this._assertObjectType(StandardObject.CONST_OBJECT_ADDRESS());
    
    // Update data.
    db.updateData(
        "CONTACT", 
        ["ADDRESS_ID"], 
        db.getColumnTypes("CONTACT", ["ADDRESS_ID"]), 
        [pAddressID], 
        "CONTACTID = '" + pContactID + "'");
}

/**
 * Will return the standard address of the given organisation. If the organisation
 * has no standard address set it will just return null.
 * 
 * @return Standard address of the organisation or null.
 */
StandardObject.prototype._getCompanyStandardAddress = function (pOrganisationID) {
    var addressIdResult = db.cell("select ADDRESS_ID from CONTACT"
        + " where ORGANISATION_ID = '" + pOrganisationID + "'"
        + " and ADDRESS_ID is not null and PERSON_ID is null");
    
    if (addressIdResult === "")
        return null;
    return addressIdResult;
}

/**
 * Checks if the given contact ID already has a standard set with the given medium
 * category.
 * 
 * @param pContactID {String} Contact ID to check.
 * @param pMediumCategory {String} Medium category to check.
 * @return {Boolean} If the contact already has a standard addres with the given
 * medium category.
 */
StandardObject.prototype._hasStandardCommunicationByMedium = function (pContactID, pMediumCategory) {   
    var dbResult = db.array(db.COLUMN, "select CHAR_VALUE from COMMUNICATION"
        + " left join AB_KEYWORD_ENTRY on KEYID = MEDIUM_ID"
        + " left join AB_KEYWORD_ATTRIBUTERELATION on AB_KEYWORD_ENTRY_ID = AB_KEYWORD_ENTRYID"
        + " where STANDARD = 1 and CONTACT_ID = '" + pContactID + "' and KEYID in ('" + CommUtil.getMediumIdsByCategory(pMediumCategory).join("', '") +  "')");
    
    return dbResult.indexOf(pMediumCategory) !== -1;
}

/**
 * Resolves the given pMediumID with the category.
 * 
 * @param pMediumID {String} ID of the medium to resolve.
 * @return {String} Resovled category.
 */
StandardObject.prototype._getMediumCategory = function (pMediumID) {
    var categories = KeywordUtils.getAttributeRelationsByKey(pMediumID, $KeywordRegistry.communicationMedium())
    
    return categories.category;
}

/**
 * Will set the given communication ID as standard. (Will update the `STANDARD`
 * column.)
 * 
 * @param pCommunicationID {String} The communication ID to set as standard.
 * @param pValue {Number} 0 or 1 (boolean)
 */
StandardObject.prototype._setStandardCommunication = function (pCommunicationID, pValue) {
    // Assert.
    this._assertObjectType(StandardObject.CONST_OBJECT_COMMUNICATION());
    
    // Update data.
    db.updateData(
        "COMMUNICATION", 
        ["STANDARD"], 
        db.getColumnTypes("COMMUNICATION", ["STANDARD"]), 
        [pValue], 
        "COMMUNICATIONID = '" + pCommunicationID + "'");
}

/**
 * Will return the Contact ID by the given communication ID.
 * 
 * @param pCommunicationID {String} Communication ID to get the contact ID for.
 * @return The contact ID.
 */
StandardObject.prototype._getContactIdByCommunication = function (pCommunicationID) {
    return db.cell("select CONTACT_ID from COMMUNICATION where COMMUNICATIONID = '" + pCommunicationID + "'");
}

StandardObject.prototype._isOrganisationAddress = function (pAddressID) {
    var contactID = db.cell("select CONTACTID from CONTACT where ADDRESS_ID = '" + pAddressID + "'");
    
    if (contactID === "")
        return false;
    
    var contactType = ContactUtils.getContactTypeByContactId(contactID);
    
    return contactType === 1;
}