Skip to content
Snippets Groups Projects
Commit 2ac7da3c authored by S.Listl's avatar S.Listl
Browse files

BulkMail check commrestriction

parent cb8e2df5
No related branches found
No related tags found
No related merge requests found
Showing
with 180 additions and 41 deletions
......@@ -18,8 +18,9 @@ var showEmpty = vars.exists("$param.ShowEmpty_param") && vars.getString("$param.
var displaySimpleName = vars.exists("$param.DisplaySimpleName_param") && vars.get("$param.DisplaySimpleName_param");
var sqlCondition = new SqlCondition();
var joinCondition = new SqlCondition();
var sqlCondition = new SqlCondition(); //where-condition (condition for the Attribute)
var joinCondition = new SqlCondition(); //condition for the joined values (for AttributeRelation)
//=> these are two distinct conditions because if showEmpty is true, a left join is used for the relations
if (vars.exists("$local.idvalues") && vars.get("$local.idvalues"))
{
......@@ -51,14 +52,14 @@ else if (showEmpty || rowId)
{
let filteredIds = JSON.parse(vars.getString("$param.FilteredAttributeIds_param"));
joinCondition.clear();
let filteredCondition = new SqlCondition();
let filteredIdChildren = AttributeUtil.getAllChildren(filteredIds);
joinCondition.andIn("AB_ATTRIBUTE.AB_ATTRIBUTEID", filteredIdChildren);
joinCondition.andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.COMBOVALUE, "# != ?")
filteredCondition.andIn("AB_ATTRIBUTE.AB_ATTRIBUTEID", filteredIdChildren);
filteredCondition.andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.COMBOVALUE, "# != ?")
// return nothing if filteredAttributeIds is an empty array. (--> and 1=2)
sqlCondition.andSqlCondition(joinCondition, "1=2");
sqlCondition.andSqlCondition(filteredCondition, "1=2");
}
}
......@@ -87,12 +88,13 @@ var defaultFields = [
var valueFields = AttributeTypeUtil.getAllDatabaseFields();
var attributeSql = SqlBuilder.begin()
.select(defaultFields.concat(valueFields))
.from("AB_ATTRIBUTE");
.from("AB_ATTRIBUTE")
.where(sqlCondition);
if (showEmpty)
attributeSql.leftJoin("AB_ATTRIBUTERELATION", joinCondition.build("1=1"));
attributeSql.leftJoin("AB_ATTRIBUTERELATION", joinCondition.build("1=2"));
else
attributeSql.join("AB_ATTRIBUTERELATION", joinCondition.build("1=1"));
attributeSql.join("AB_ATTRIBUTERELATION", joinCondition.build("1=2"));
attributeSql.leftJoin("AB_ATTRIBUTE", "COMBOVAL.AB_ATTRIBUTEID = " + $AttributeTypes.COMBO.databaseField, "COMBOVAL");
......
......@@ -28,4 +28,4 @@ for (let i = 0, l = contactIds.length; i < l; i++)
{
inserts.push(["BULKMAILRECIPIENT", columns, null, [util.getNewUUID(), bulkMailId, contactIds[i], $KeywordRegistry.bulkMailRecipientStatus$pending()]]);
}
db.inserts(inserts);
\ No newline at end of file
db.inserts(inserts);
......@@ -78,6 +78,7 @@
</entityField>
<entityField>
<name>ICON</name>
<colorProcess>%aditoprj%/entity/BulkMailRecipient_entity/entityfields/icon/colorProcess.js</colorProcess>
<contentType>IMAGE</contentType>
<valueProcess>%aditoprj%/entity/BulkMailRecipient_entity/entityfields/icon/valueProcess.js</valueProcess>
</entityField>
......@@ -94,6 +95,9 @@
<resolution>MINUTE</resolution>
<outputFormat>dd.MM.yyyy HH:mm</outputFormat>
</entityField>
<entityField>
<name>HASCOMMRESTRICTION</name>
</entityField>
</entityFields>
<recordContainers>
<dbRecordContainer>
......@@ -134,10 +138,6 @@
<name>STATUS.value</name>
<recordfield>BULKMAILRECIPIENT.STATUS</recordfield>
</dbRecordFieldMapping>
<dbRecordFieldMapping>
<name>EMAIL_ADDRESS.displayValue</name>
<expression>%aditoprj%/entity/BulkMailRecipient_entity/recordcontainers/db/recordfieldmappings/email_address.displayvalue/expression.js</expression>
</dbRecordFieldMapping>
<dbRecordFieldMapping>
<name>ORGANISATION_ID.value</name>
<recordfield>CONTACT.ORGANISATION_ID</recordfield>
......@@ -162,6 +162,14 @@
<name>CONTACT_ID.displayValue</name>
<expression>%aditoprj%/entity/BulkMailRecipient_entity/recordcontainers/db/recordfieldmappings/contact_id.displayvalue/expression.js</expression>
</dbRecordFieldMapping>
<dbRecordFieldMapping>
<name>HASCOMMRESTRICTION.value</name>
<expression>%aditoprj%/entity/BulkMailRecipient_entity/recordcontainers/db/recordfieldmappings/hascommrestriction.value/expression.js</expression>
</dbRecordFieldMapping>
<dbRecordFieldMapping>
<name>EMAIL_ADDRESS.value</name>
<expression>%aditoprj%/entity/BulkMailRecipient_entity/recordcontainers/db/recordfieldmappings/email_address.value/expression.js</expression>
</dbRecordFieldMapping>
</recordFieldMappings>
</dbRecordContainer>
</recordContainers>
......
import("system.vars");
import("system.result");
import("system.neon");
if (vars.get("$field.HASCOMMRESTRICTION") == "true" || !vars.get("$field.EMAIL_ADDRESS"))
result.string(neon.PRIORITY_HIGH_COLOR);
\ No newline at end of file
......@@ -4,7 +4,9 @@ import("Contact_lib");
var type = ContactUtils.getContactTypeByPersOrg(vars.get("$field.PERSON_ID"), vars.get("$field.ORGANISATION_ID"));
var icon;
if (type == 1)
if (vars.get("$field.HASCOMMRESTRICTION") == "true")
icon = "VAADIN:BAN";
else if (type == 1)
icon = "VAADIN:BUILDING";
else if (type >= 2)
icon = "VAADIN:USER";
......
import("system.db");
import("Bulkmail_lib");
import("system.result");
var commRestrictionCond = BulkMailUtils.getCommRestrictionCondition(true).build();
var sql = "case when (" + db.translateStatement(commRestrictionCond) + ") then 'true' else 'false' end";
result.string(sql);
import("system.translate");
import("system.db");
import("Bulkmail_lib");
import("system.result");
import("Keyword_lib");
import("KeywordRegistry_basic");
var sql = KeywordUtils.getResolvedTitleSqlPart($KeywordRegistry.bulkMailRecipientStatus(), "BULKMAILRECIPIENT.STATUS");
var commRestrictionCond = BulkMailUtils.getCommRestrictionCondition(true).build();
var keywordSql = KeywordUtils.getResolvedTitleSqlPart($KeywordRegistry.bulkMailRecipientStatus(), "BULKMAILRECIPIENT.STATUS");
var sql = "case when (" + db.translateStatement(commRestrictionCond)
+ ") then '" + translate.text("Advertising ban")
+ "' else (" + keywordSql + ") end";
result.string(sql);
......@@ -495,6 +495,13 @@
<name>expanded</name>
<valueProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/expanded/valueProcess.js</valueProcess>
</entityField>
<entityActionField>
<name>openAdminView</name>
<title>Open admin view</title>
<onActionProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/openadminview/onActionProcess.js</onActionProcess>
<iconId>VAADIN:CURLY_BRACKETS</iconId>
<stateProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/openadminview/stateProcess.js</stateProcess>
</entityActionField>
</entityFields>
<recordContainers>
<dbRecordContainer>
......
import("system.vars");
import("Context_lib");
AdminViewUtils.open("AB_KEYWORD_ENTRYID", [
["KEYID", vars.get("$field.KEYID")]
]);
\ No newline at end of file
import("Context_lib");
import("system.result");
result.string(AdminViewUtils.getActionState());
\ No newline at end of file
......@@ -865,8 +865,8 @@
<value>Werbemittel</value>
</entry>
<entry>
<key>%0 mails sent sucessfully, %1 mails failed</key>
<value>%0 Mails erfolgreich versendet, %1 Mails fehlgeschlagen</value>
<key>%0 mails sent sucessfully, %1 mails failed. Process took %2 s.</key>
<value>%0 Mails erfolgreich versendet, %1 Mails fehlgeschlagen. Ausführung dauerte %2 s.</value>
</entry>
<entry>
<key>Valid from</key>
......
How to use the SqlBuilder (state: 10.07.2019)
==============================================
:toc2: left
:numbered:
== What is SqlBuilder? ==
A SqlBuilder object helps to build sql queries.
== Why would I need that? ==
SqlBuilder makes it easier to build complex queries while maintaining clean code,
especially if you want to append sql parts dynamically. With SqlBuilder you can also use SqlCondition
objects in many parts of the query at the same time, for example in join, where or having clauses.
== How to use it ==
* import the lib:
[source,javascript]
----
import("Sql_lib");
----
* create an object ()
[source,javascript]
----
var myDescriptiveNameOfTheQuery = new SqlBuilder();
// or
var myDescriptiveNameOfTheQuery = SqlBuilder.begin();
----
* use the object, set clauses
[source,javascript]
----
myDescriptiveNameOfTheQuery.select(["PERSON.FIRSTNAME", "PERSON.LASTNAME"]) //you can use an array or a string here
.from("PERSON")
.join("CONTACT", SqlCondition.begin()
.and("CONTACT.PERSON_ID = PERSON.PERSONID"))
.where(SqlCondition.begin()
.andPrepare("CONTACT.CONTACTID", contactId)
.build("1=1"));
----
* Using .build on the SqlCondition is optional, but you could use it to set the alternative condition.
* Before using the sql, call .build():
[source,javascript]
----
var names = db.table(myDescriptiveNameOfTheQuery.build());
----
== available methods ==
see the comments and documentation in the lib
......@@ -52,8 +52,9 @@ BulkMailUtils.sendBulkMail = function (pBulkMailId)
var recipientData = db.table(SqlCondition.begin()
.andPrepare("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId)
.andPrepare("BULKMAILRECIPIENT.STATUS", $KeywordRegistry.bulkMailRecipientStatus$sent(), "# != ?")
//and no advertising ban
.buildSql("select BULKMAILRECIPIENTID, CONTACT_ID, '' from BULKMAILRECIPIENT", "1=2")
.andSqlCondition(BulkMailUtils.getCommRestrictionCondition())
.buildSql("select BULKMAILRECIPIENTID, BULKMAILRECIPIENT.CONTACT_ID, '' from BULKMAILRECIPIENT \n\
join CONTACT on BULKMAILRECIPIENT.CONTACT_ID = CONTACT.CONTACTID", "1=2")
);
var contactIds = recipientData.map(function (e) {return e[1];});
var successIds = [];
......@@ -69,12 +70,11 @@ BulkMailUtils.sendBulkMail = function (pBulkMailId)
let isSuccess = false;
let contactId = recipientData[i][1];
let email = mails[contactId];
if (email !== undefined)
if (email !== undefined && recipientData[i][2])
{
email.toRecipients = [recipientData[i][2]]; //TODO: email address missing
email.sender = emailSender;
email.subject = subjects[contactId];
email.sender = sender;
isSuccess = email.send();
}
......@@ -115,14 +115,17 @@ BulkMailUtils.openAddRecipientView = function (pContactIds)
BulkMailUtils.getCommRestrictionCondition = function (pPositive)
{
var currentDate = datetime.date();
var existsQuery = SqlCondition.begin()
.andPrepare("COMMRESTRICTION.MEDIUM", $KeywordRegistry.communicationMediumCampaign$mail())
.andPrepare("COMMRESTRICTION.STARTDATE", currentDate, "# <= ?")
.and("COMMRESTRICTION.CONTACT_ID = CONTACT.CONTACTID or COMMRESTRICTION.CONTACT_ID = CONTACT.PERSON_ID")
.buildSql("exists(select COMMRESTRICTIONID from COMMRESTRICTION", "1=2", ")");
existsQuery = db.translateCondition(existsQuery);
var existsQuery = SqlBuilder.begin()
.select("COMMRESTRICTIONID")
.from("COMMRESTRICTION")
.where(SqlCondition.begin()
.andPrepare("COMMRESTRICTION.MEDIUM", $KeywordRegistry.communicationMediumCampaign$mail())
.andPrepare("COMMRESTRICTION.STARTDATE", currentDate, "# <= ?")
.and("COMMRESTRICTION.CONTACT_ID = CONTACT.CONTACTID or COMMRESTRICTION.CONTACT_ID = CONTACT.PERSON_ID")
.build("1=2"));
var cond = "exists";
if (!pPositive)
existsQuery = "not " + existsQuery;
return SqlCondition.begin().and(existsQuery);
}
\ No newline at end of file
cond = "not " + cond;
return SqlCondition.begin().andSqlBuilder(existsQuery, cond);
}
......@@ -178,6 +178,42 @@ SqlCondition.prototype.orSqlCondition = function(cond, alternativeCond) {
return this;
}
/**
* append an condition that uses a subQuery with SQL-and
*
* @param {SqlBuilder} subQuery the SqlBuilder object that will be used as a subquery
* @param {String} [cond="exists"] condition that is used (e. g. exists, not exists, COLUMN = any, COLUMN in, ...)
* @return {SqlCondition} current SqlCondition-object
*/
SqlCondition.prototype.andSqlBuilder = function(subQuery, cond) {
if (!cond)
cond = "exists";
var preparedObj = subQuery.build();
preparedObj[0] = cond + " ( " + preparedObj[0] + " ) ";
this.andAttachPrepared(preparedObj);
return this;
}
/**
* append an condition that uses a subQuery with SQL-or
*
* @param {SqlBuilder} subQuery the SqlBuilder object that will be used as a subquery
* @param {String} [cond="exists"] condition that is used (e. g. exists, not exists, COLUMN = any, COLUMN in, ...)
* @return {SqlCondition} current SqlCondition-object
*/
SqlCondition.prototype.orSqlBuilder = function(subQuery, cond) {
if (!cond)
cond = "exists";
var preparedObj = subQuery.build();
preparedObj[0] = cond + " ( " + preparedObj[0] + " ) ";
this.orAttachPrepared(preparedObj);
return this;
}
/**
* same as the "and"-function but with preparedStatement functionality
* @param {String | String[]} field the database field as "tablename.columnname"; e.g. "ORGANISATION.NAME" or as array with column-alias: ["ORGANISATION", "NAME", "myorgAlias"]
......@@ -649,7 +685,7 @@ SqlBuilder.prototype.toString = function ()
}
/**
* Adds a select clause to the sql.
* Sets the select clause of the sql.
* @param {String|String[]} pFields
* @return {SqlBuilder} current SqlBuilder object
*/
......@@ -660,7 +696,7 @@ SqlBuilder.prototype.select = function (pFields)
}
/**
* Adds a select distinct clause to the sql.
* Sets the select clause of the sql with distinct.
* @param {String|String[]} pFields
* @return {SqlBuilder} current SqlBuilder object
*/
......@@ -671,7 +707,7 @@ SqlBuilder.prototype.selectDistinct = function (pFields)
}
/**
* Adds a from clause to the sql.
* Sets the from clause of the sql.
* @param {String} pTable
* @param {String} [pAlias] table alias
* @return {SqlBuilder} current SqlBuilder object
......@@ -719,7 +755,7 @@ SqlBuilder.prototype.leftJoin = function (pTable, pCondition, pAlias)
}
/**
* Adds a where clause to the sql.
* Sets the where clause of the sql.
*
* @param {String|String[]|SqlCondition} pCondition The where condition. This can be
* a string (without the where keyword), a SqlCondition or an array (for prepared queries).
......@@ -733,7 +769,7 @@ SqlBuilder.prototype.where = function (pCondition)
}
/**
* Adds a order by clause to the sql.
* Sets the order by clause of the sql.
* @param {String} pOrderBy
* @return {SqlBuilder} current SqlBuilder object
*/
......@@ -744,7 +780,7 @@ SqlBuilder.prototype.orderBy = function (pOrderBy)
}
/**
* Adds a group by clause to the sql.
* Sets the group by clause of the sql.
* @param {String|String[]} pFields
* @return {SqlBuilder} current SqlBuilder object
*/
......@@ -793,7 +829,7 @@ SqlBuilder.prototype.having = function (pCondition)
/**
* generates a part of the sql
*
* @param {String|String[]|SqlBuilder} pElement the element to append
* @param {String|String[]|SqlBuilder|SqlCondition} pElement the element to append
* @param {String} [pPrefix] string to be added before pElement
* @param {Boolean} [pAutoJoin] if this is true and pElement is an array, it will be automatically
* joined together to a string
......@@ -832,7 +868,7 @@ SqlBuilder.prototype._getClause = function (pElement, pPrefix, pAutoJoin)
function _getElement (element)
{
let condition = element.build();
element = element.build();
preparedValues = preparedValues.concat(element[1]);
if (element instanceof SqlBuilder)
return "(" + element[0] + ")";
......
import("system.datetime");
import("Sql_lib");
import("system.db");
import("system.util");
......@@ -6,6 +7,7 @@ import("Bulkmail_lib");
import("system.vars");
import("system.notification");
var startTime = datetime.date();
var bulkMailId = vars.get("$local.bulkMailId");
var user = vars.get("$local.user");
var res = BulkMailUtils.sendBulkMail(bulkMailId);
......@@ -17,6 +19,7 @@ if (user)
.buildSql("select NAME from BULKMAIL")
);
var message = translate.withArguments("Bulk mail \"%0\" was sent!", [mailName]);
var description = translate.withArguments("%0 mails sent sucessfully, %1 mails failed", [res.sucessful, res.failed]);
var description = translate.withArguments("%0 mails sent sucessfully, %1 mails failed. Process took %2 s.",
[res.sucessful, res.failed, Math.round((datetime.date() - startTime) / datetime.ONE_SECOND)]);
notification.addNotification(util.getNewUUID(), null, null, null, "BulkMailSent", notification.PRIO_NORMAL, 2, notification.STATE_UNSEEN, [user], message, description);
}
\ No newline at end of file
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