Skip to content
Snippets Groups Projects
Commit 01b8c716 authored by Johannes Goderbauer's avatar Johannes Goderbauer
Browse files

prevent duplicate contacts (same ORGANISATION and PERSON)

parent 38c1367e
No related branches found
No related tags found
No related merge requests found
......@@ -12,7 +12,7 @@ var organisationId = ProcessHandlingUtils.getOnValidationValue("$field.ORGANISAT
//but the field already contains the changed value; so let's load the field instead of the $local.value-variable
//this is a bug within the ADITO-kernel
//TODO: change the workaround behaviour when $local.value is retrieved correct
organisationId = vars.getString("$field.ORGANISATION_ID")
organisationId = vars.getString("$field.ORGANISATION_ID");
if (personId)
{
......
......@@ -129,12 +129,6 @@
<fieldName>Organisations</fieldName>
<isConsumer v="false" />
</entityDependency>
<entityDependency>
<name>19a28531-bec6-49e2-b00d-aae3816e6690</name>
<entityName>Person_entity</entityName>
<fieldName>Organisations</fieldName>
<isConsumer v="false" />
</entityDependency>
</dependencies>
<children>
<entityParameter>
......@@ -656,6 +650,12 @@
<fieldName>Organisations</fieldName>
<isConsumer v="false" />
</entityDependency>
<entityDependency>
<name>a80c3db0-29db-433c-8f7c-4ebf6639ad6d</name>
<entityName>Person_entity</entityName>
<fieldName>Organisations</fieldName>
<isConsumer v="false" />
</entityDependency>
</dependencies>
<children>
<entityParameter>
......
......@@ -157,6 +157,7 @@
<searchable v="true" />
<valueProcess>%aditoprj%/entity/Person_entity/entityfields/organisation_id/valueProcess.js</valueProcess>
<displayValueProcess>%aditoprj%/entity/Person_entity/entityfields/organisation_id/displayValueProcess.js</displayValueProcess>
<onValidation>%aditoprj%/entity/Person_entity/entityfields/organisation_id/onValidation.js</onValidation>
</entityField>
<entityConsumer>
<name>PersAddresses</name>
......@@ -208,12 +209,16 @@ Usually this is used for filtering COMMUNICATION-entries by a specified contact
<dependency>
<name>dependency</name>
<entityName>Organisation_entity</entityName>
<fieldName>Organisations</fieldName>
<fieldName>WithPersonIdFilter</fieldName>
</dependency>
<children>
<entityParameter>
<name>WithPrivate_param</name>
</entityParameter>
<entityParameter>
<name>ExcludeOrganisationsByPersonId</name>
<valueProcess>%aditoprj%/entity/Person_entity/entityfields/organisations/children/excludeorganisationsbypersonid/valueProcess.js</valueProcess>
</entityParameter>
</children>
</entityConsumer>
<entityConsumer>
......
import("system.logging");
import("system.translate");
import("system.result");
import("system.db");
import("system.vars");
import("system.neon");
import("Entity_lib");
import("Contact_lib");
import("Sql_lib");
//TODO: comment
//TODO: into lib
//TODO: use in Contact
ContactUtils.validateOrganisationId = function(pPersonId, pOrganisationId, pOwnContactId)
{
if (!pPersonId)
return null;
if (pOrganisationId == "")
pOrganisationId = "0";
var cond = SqlCondition.begin()
.andPrepare("CONTACT.PERSON_ID", pPersonId)
.andPrepare("CONTACT.ORGANISATION_ID", pOrganisationId)
//exclude the own since we do not want a "is not valid"-message for our own entry (on EDIT-mode)
.andPrepareIfSet("CONTACT.CONTACTID", pOwnContactId, "# != ?");
var sql = cond.buildSql("select CONTACT.CONTACTID from CONTACT");
var alreadyExistantContactId = db.cell(sql);
if (alreadyExistantContactId)
if (pOrganisationId.trim() == "0")
return translate.text("This private person doeas already exist and can not be created once more.");
else
return translate.text("This combination of person and organisation does already exist and can not be created once more.");
return null;
};
var personId = vars.getString("$field.PERSONID");
var organisationId = ProcessHandlingUtils.getOnValidationValue("$field.ORGANISATION_ID");
var contactId;//in EDIT we have to exclude our own CONTACTID since we do not want a message for our own contactentry
if (vars.get("$sys.recordstate") != neon.OPERATINGSTATE_NEW)
contactId = vars.get("$field.CONTACTID");
//workaround for organisationId: $local.value will return the name of the organisation which is not what we want
//but the field already contains the changed value; so let's load the field instead of the $local.value-variable
//this is a bug within the ADITO-kernel
//TODO: change the workaround behaviour when $local.value is retrieved correct
organisationId = vars.getString("$field.ORGANISATION_ID");
var validationMsg = ContactUtils.validateOrganisationId(personId, organisationId, contactId);
if (validationMsg)
result.string(validationMsg);
\ No newline at end of file
import("system.vars");
import("system.result");
import("system.neon");
//in mode NEW no record with that PERSONID exists that could be excluded by a database query, so let's ignore that (which means do not pass a value)
if (vars.get("$sys.recordstate") != neon.OPERATINGSTATE_NEW)
result.object(vars.get("$field.PERSONID"));
\ No newline at end of file
......@@ -204,6 +204,46 @@ SqlCondition.prototype.orPrepare = function(field, value, cond, fieldType) {
return this.or(cond);
}
/**
* same as the "andPrepare"-function but only applied if the passed "value" is truely
* @param {String | String[]} field the database field as "tablename.columnname"; e.g. "ORGANISATION.NAME" or as array with column-alias: ["ORGANISATION", "NAME", "myorgAlias"]
* @param {String} value the value that shall be set into the prepared statement
* @param {String} [cond="# = ?"] the strucutre of the SQL condition as preparedString, you can use a number sign "#" as placeholder for you fieldname;
* e.g. "# > ?"; escaping the number sign is possible with a backslash "\"
* @param {Numeric | Boolean} [fieldType] SQL-column-type; if the fieldType is not given it's loaded automatically;
* The loaded type is cached if no type is given. So it is also safe to use this in a loop.
* e.g.
* for (...) {
* cond.andPrepare("SALESPROJECT_CLASSIFICATION.TYPE", entry, "# <> ?")
* }
* @return {SqlCondition} current SqlCondition-object
*/
SqlCondition.prototype.andPrepareIfSet = function(field, value, cond, fieldType) {
if (value)
return this.andPrepare(field, value, cond, fieldType);
return this;
}
/**
* same as the "orPrepare"-function but only applied if the passed "value" is truely
* @param {String | String[]} field the database field as "tablename.columnname"; e.g. "ORGANISATION.NAME" or as array with column-alias: ["ORGANISATION", "NAME", "myorgAlias"]
* @param {String} value the value that shall be set into the prepared statement
* @param {String} [cond="# = ?"] the strucutre of the SQL condition as preparedString, you can use a number sign "#" as placeholder for you fieldname;
* e.g. "# > ?"; escaping the number sign is possible with a backslash "\"
* @param {Numeric | Boolean} [fieldType] SQL-column-type; if the fieldType is not given it's loaded automatically;
* The loaded type is cached if no type is given. So it is also safe to use this in a loop.
* e.g.
* for (...) {
* cond.andPrepare("SALESPROJECT_CLASSIFICATION.TYPE", entry, "# <> ?")
* }
* @return {SqlCondition} current SqlCondition-object
*/
SqlCondition.prototype.orPrepareIfSet = function(field, value, cond, fieldType) {
if (value)
return this.orPrepare(field, value, cond, fieldType);
return this;
}
/**
* same as the "andPrepare"-function but with validation of adito-variables functionality
* @param {String | String[]} field the database field as "tablename.columnname"; e.g. "ORGANISATION.NAME" or as array with column-alias: ["ORGANISATION", "NAME", "myorgAlias"]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment