blob: dc45a4e8e96036ce05a55679f35fa2ea4b50bdef [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.ofbiz.base.util.UtilDateTime
import org.apache.ofbiz.base.util.UtilProperties
import org.apache.ofbiz.entity.GenericValue
import org.apache.ofbiz.entity.condition.EntityCondition
import org.apache.ofbiz.entity.condition.EntityOperator
import org.apache.ofbiz.party.party.PartyHelper
import org.apache.ofbiz.service.ModelService
import java.sql.Timestamp
/**
* Create a CommunicationEvent with or w/o permission check
*/
Map createCommunicationEvent() {
GenericValue newCommEvent
// check for forward only if created by a user and not incoming email by system
if (parameters.action == 'FORWARD'
&& parameters.origCommEventId) {
newCommEvent = from('CommunicationEvent')
.where('communicationEventId', parameters.origCommEventId)
.queryOne()
newCommEvent.remove('communicationEventId')
newCommEvent.remove('messageId')
newCommEvent.remove('partyIdTo')
newCommEvent.partyIdFrom = parameters.partyIdTo
String forwardLabel = UtilProperties.getPropertyValue('PartyUiLabels', 'PartyForward')
newCommEvent.subject = "${forwardLabel}: ${newCommEvent.subject}"
newCommEvent.origCommEventId = parameters.origCommEventId
}
// init communication event fields
newCommEvent = newCommEvent ?: makeValue('CommunicationEvent')
newCommEvent.setNonPKFields(parameters)
newCommEvent.communicationEventId = parameters.communicationEventId ?:
delegator.getNextSeqId('CommunicationEvent')
// check for reply or reply all
GenericValue parentCommEvent
if (parameters.parentCommEventId
&& (parameters.action == 'REPLY'
|| parameters.action == 'REPLYALL')) {
parentCommEvent = from('CommunicationEvent')
.where('communicationEventId', parameters.parentCommEventId)
.queryOne()
GenericValue party = from('Party')
.where('partyId', parameters.partyIdFrom)
.queryOne()
newCommEvent.communicationEventTypeId = parentCommEvent.communicationEventTypeId
if (newCommEvent.communicationEventTypeId == 'AUTO_EMAIL_COMM') {
newCommEvent.communicationEventTypeId = 'EMAIL_COMMUNICATION'
}
newCommEvent.partyIdFrom = parameters.partyIdFrom ?: parameters.userLogin.partyId
newCommEvent.partyIdTo = parentCommEvent.partyIdFrom
newCommEvent.parentCommEventId = parentCommEvent.communicationEventId
newCommEvent.subject = 'RE: ' + parentCommEvent.subject
newCommEvent.contentMimeTypeId = parentCommEvent.contentMimeTypeId
//create the content as response
String localContent = parentCommEvent.content
String resultLine = ''
if (localContent) {
resultLine = PartyHelper.getPartyName(party) +
'\n\n > ' +
localContent.substring(0, localContent.indexOf('\n', 0) == -1
? localContent.length()
: localContent.indexOf('\n', 0))
int startChar = localContent.indexOf('\n', 0)
while (startChar != -1 && (startChar = localContent.indexOf('\n', startChar) + 1) != 0) {
resultLine += '\n > ' + localContent.substring(startChar,
localContent.indexOf('\n', startChar) == -1
? localContent.length()
: localContent.indexOf('\n', startChar))
}
}
newCommEvent.content = resultLine.toString()
// set role status from the parent commevent to completed
GenericValue role = from('CommunicationEventRole')
.where([communicationEventId: parentCommEvent.communicationEventId,
partyId: newCommEvent.partyIdFrom])
.queryFirst()
if (role) {
Map setCommEventRoleStatusMap = [*: role]
setCommEventRoleStatusMap.statusId = 'COM_ROLE_COMPLETED'
run service: 'setCommunicationEventRoleStatus', with: setCommEventRoleStatusMap
}
}
newCommEvent.statusId = newCommEvent.statusId ?: 'COM_ENTERED'
if (newCommEvent.communicationEventTypeId == 'EMAIL_COMMUNICATION') {
['From', 'To'].each {
// if only contactMechId[From/To] and no partyId[From/To] is provided for creation email address find the related part
if (!newCommEvent."partyId${it}"
&& newCommEvent."contactMechId${it}") {
GenericValue partyContactMech = from('PartyAndContactMech')
.where([contactMechId: newCommEvent."contactMechId${it}",
contactMechTypeId: 'EMAIL_ADDRESS'])
.queryFirst()
if (partyContactMech) {
newCommEvent."partyId${it}" = partyContactMech.partyId
}
} else {
//if partyId[From/To] provided but no contactMechId[From/To] get emailAddress
if (newCommEvent."partyId${it}"
&& !newCommEvent."contactMechId${it}") {
Map getPartyEmailResult = run service: 'getPartyEmail', with: [partyId: newCommEvent."partyId${it}"]
newCommEvent."contactMechId${it}" = getPartyEmailResult.contactMechId
}
}
}
}
newCommEvent.entryDate = UtilDateTime.nowTimestamp()
newCommEvent.create()
if (parentCommEvent && parameters.action == 'REPLYALL') {
List<GenericValue> roles = from('CommunicationEventRole')
.where([EntityCondition.makeCondition('communicationEventId', parentCommEvent.communicationEventId),
EntityCondition.makeCondition('partyId', EntityOperator.NOT_IN,
[newCommEvent.partyIdFrom, newCommEvent.partyIdTo])])
.queryList()
if (roles) {
roles.each {
Map newCommEventRole = [*:it]
newCommEventRole.communicationEventId = newCommEvent.communicationEventId
run service: 'createCommunicationEventRole', with: newCommEventRole
}
}
}
if (parameters.productId) {
GenericValue commEventProduct = makeValue('CommunicationEventProduct', parameters)
commEventProduct.communicationEventId = newCommEvent.communicationEventId
commEventProduct.create()
}
if (parameters.orderId) {
GenericValue commEventOrder = makeValue('CommunicationEventOrder', parameters)
commEventOrder.communicationEventId = newCommEvent.communicationEventId
commEventOrder.create()
}
if (parameters.returnId) {
GenericValue commEventReturn = makeValue('CommunicationEventReturn', parameters)
commEventReturn.communicationEventId = newCommEvent.communicationEventId
commEventReturn.create()
}
if (parameters.custRequestId) {
Map commEventRequestContext = [custRequestId: parameters.custRequestId,
communicationEventId: newCommEvent.communicationEventId]
run service: 'createCustRequestCommEvent', with: commEventRequestContext
}
// partyIdTo role
if (newCommEvent.partyIdTo) {
Map createCommEvenRoleContext = [
communicationEventId: newCommEvent.communicationEventId,
partyId: newCommEvent.partyIdTo,
contactMechId: newCommEvent.contactMechIdTo,
roleTypeId: 'ADDRESSEE']
run service: 'createCommunicationEventRole', with: createCommEvenRoleContext
}
// partyIdFrom role
if (newCommEvent.partyIdFrom) {
Map createCommEvenRoleContext = [
communicationEventId: newCommEvent.communicationEventId,
partyId: newCommEvent.partyIdFrom,
contactMechId: newCommEvent.contactMechIdFrom,
roleTypeId: 'ORIGINATOR',
statusId: 'COM_ROLE_COMPLETED']
run service: 'createCommunicationEventRole', with: createCommEvenRoleContext
}
Map result = success()
result.communicationEventId = newCommEvent.communicationEventId
return result
}
/**
* create a CommunicationEvent without permission, use run service auto-matching to populate missing user
*/
Map createCommunicationEventWithoutPermission() {
GenericValue system = from('UserLogin').where(userLoginId: 'system').cache().queryOne()
Map result = run service: 'createCommunicationEvent', with: [*:parameters,
userLogin: system]
return result
}
/**
* Update a CommunicationEvent
*/
Map updateCommunicationEvent() {
GenericValue event = from('CommunicationEvent')
.where(parameters)
.queryOne()
Map fieldsMap = [*:parameters]
String newStatusId = null
if (event.statusId != parameters.statusId) {
newStatusId = parameters.statusId
fieldsMap.statusId = event.statusId
}
// get partyId from email address if required
if (!parameters.partyIdTo && parameters.contactMechIdTo) {
GenericValue partyContactMech = from('PartyAndContactMech')
.where(contactMechId: parameters.contactMechIdTo)
.filterByDate()
.queryFirst()
fieldsMap.partyIdTo = partyContactMech ?
partyContactMech.partyId : null
}
// if the from-party changed, change also the roles
if (parameters.partyIdFrom
&& parameters.partyIdFrom != event.partyIdFrom) {
// updating partyId from old:
if (event.partyIdFrom) {
GenericValue roleFrom = from('CommunicationEventRole')
.where([communicationEventId: event.communicationEventId,
partyId: event.partyIdFrom,
roleTypeId: 'ORIGINATOR'])
.queryOne()
roleFrom?.remove()
}
// add new role
Map createCommEventRoleMap = [partyId: parameters.partyIdFrom]
createCommEventRoleMap.contactMechPurposeTypeIdFrom = parameters.contactMechPurposeTypeIdFrom ?: ''
Map getPartyEmailFrom = run service: 'getPartyEmail', with: createCommEventRoleMap
createCommEventRoleMap.contactMechId = getPartyEmailFrom.contactMechId
createCommEventRoleMap.communicationEventId = event.communicationEventId
createCommEventRoleMap.roleTypeId = 'ORIGINATOR'
run service: 'createCommunicationEventRole', with: createCommEventRoleMap
fieldsMap.contactMechIdFrom = createCommEventRoleMap.contactMechId
}
// if the to-party changed, change also the roles
if (parameters.partyIdTo
&& parameters.partyIdTo != event.partyIdTo) {
if (event.partyIdTo) {
GenericValue roleTo = from('CommunicationEventRole')
.where([communicationEventId: event.communicationEventId,
partyId: event.partyIdto,
roleTypeId: 'ADDRESSEE'])
.queryOne()
roleTo?.remove()
}
// add new role
Map createCommEventRoleMap = [partyId: parameters.partyIdTo]
Map getPartyEmailTo = run service: 'getPartyEmail', with: createCommEventRoleMap
createCommEventRoleMap.contactMechId = getPartyEmailTo.contactMechId
createCommEventRoleMap.communicationEventId = event.communicationEventId
createCommEventRoleMap.roleTypeId = 'ADDRESSEE'
run service: 'createCommunicationEventRole', with: createCommEventRoleMap
fieldsMap.contactMechIdTo = createCommEventRoleMap.contactMechId
}
event.setNonPKFields(fieldsMap)
event.store()
if (newStatusId) {
fieldsMap.statusId = newStatusId
run service: 'setCommunicationEventStatus', with: fieldsMap
}
return success()
}
/**
* Delete a CommunicationEvent
*/
Map deleteCommunicationEvent() {
GenericValue event = from('CommunicationEvent')
.where(parameters)
.queryOne()
// the service can be called multiple times because event can have several recipients
// ignore if already deleted
if (!event) {
return success()
}
// remove related links to work effort and product
event.removeRelated('CommunicationEventWorkEff')
event.removeRelated('CommunicationEventProduct')
List<GenericValue> contentAssocs = event.getRelated('CommEventContentAssoc', null, null, false)
contentAssocs.each { contentAssoc ->
contentAssoc.remove()
//Delete content and dataresource too if requested
if (parameters.delContentDataResource == 'Y') {
List<GenericValue> contents = contentAssoc.getRelated('FromContent', null, null, false)
contents.each { content ->
content.removeRelated('ContentRole')
content.removeRelated('ContentKeyword')
List<GenericValue> relatedFromContentassocs = content.getRelated('FromContentAssoc', null, null, false)
relatedFromContentassocs.each { relatedFromContentassoc ->
Map removeContentAndRelatedInmap = [contentId: relatedFromContentassoc.contentIdTo]
run service: 'removeContentAndRelated', with: removeContentAndRelatedInmap
}
content.removeRelated('FromContentAssoc')
List<GenericValue> relatedToContentassocs = content.getRelated('ToContentAssoc', null, null, false)
relatedToContentassocs.each { relatedFromContentassoc ->
Map removeContentAndRelatedInmap = [contentId: relatedFromContentassoc.contentIdFrom]
run service: 'removeContentAndRelated', with: removeContentAndRelatedInmap
}
content.removeRelated('ToContentAssoc')
content.remove()
// check first if the content is used on any other communication event if yes, only delete link
List<GenericValue> commEvents = from('CommEventContentAssoc')
.where('contentId', content.contentId)
.queryList()
if (commEvents && commEvents.size() == 1) {
Map removeContentAndRelatedInmap = [contentId: content.contentId]
run service: 'removeContentAndRelated', with: removeContentAndRelatedInmap
}
}
}
}
//delete the roles when exist and the event itself
event.removeRelated('CommunicationEventRole')
event.remove()
return success()
}
/**
* delete commEvent and workEffort
*/
Map deleteCommunicationEventWorkEffort() {
GenericValue event = from('CommunicationEvent')
.where(parameters)
.queryOne()
// remove related workeffort when this is the only communicationevent connected to it
List<GenericValue> workEffortComs = event.getRelated('CommunicationEventWorkEff', null, null, false)
workEffortComs.each { workEffortCom ->
workEffortCom.remove()
GenericValue workEffort = workEffortCom.getRelatedOne('WorkEffort', false)
List<GenericValue> otherComs = workEffort.getRelated('CommunicationEventWorkEff', null, null, false)
if (!otherComs) {
logInfo("remove workeffort ${workEffort.workEffortId} and related parties and status")
workEffort.removeRelated('WorkEffortPartyAssignment')
workEffort.removeRelated('WorkEffortStatus')
workEffort.removeRelated('WorkEffortKeyword')
workEffort.remove()
}
}
run service: 'deleteCommunicationEvent', with: parameters
return success()
}
/**
* Create a CommunicationEventRole
*/
Map createCommunicationEventRole() {
// check if role already exist, then ignore
GenericValue communicationEventRole =
from('CommunicationEventRole')
.where(parameters)
.queryOne()
if (!communicationEventRole) {
GenericValue sysUserLogin = from('UserLogin').where(userLoginId: 'system').queryOne()
Map partyRole = parameters
partyRole.userLogin = sysUserLogin
run service: 'ensurePartyRole', with: partyRole
GenericValue newEntity = makeValue('CommunicationEventRole')
newEntity.setPKFields(parameters)
newEntity.setNonPKFields(parameters)
newEntity.statusId = parameters.statusId ?: 'COM_ROLE_CREATED'
// if not provided get the latest contact mech id
if (!newEntity.contactMechId) {
GenericValue communicationEvent =
from('CommunicationEvent').where(communicationEventId: context.communicationEventId)
.queryOne()
GenericValue communicationEventType = communicationEvent.getRelatedOne('CommunicationEventType')
if (communicationEventType.contactMechTypeId) {
GenericValue contactMech = from('PartyAndContactMech')
.where('partyId', newEntity.partyId,
'contactMechTypeId', communicationEventType.contactMechTypeId)
.orderBy('-fromDate')
.queryFirst()
if (contactMech) {
newEntity.contactMechId = contactMech.contactMechId
}
}
}
newEntity.create()
return success()
}
return success()
}
/**
* Remove a CommunicationEventRole
*/
Map removeCommunicationEventRole() {
GenericValue eventRole = from('CommunicationEventRole')
.where(parameters)
.queryOne()
if (eventRole) {
eventRole.remove()
if (parameters.deleteCommEventIfLast == 'Y'
&& from('CommunicationEventRole')
.where('communicationEventId', eventRole.communicationEventId)
.queryCount() == 0) {
run service: 'deleteCommunicationEvent', with: parameters
}
}
return success()
}
/**
* Checks for email communication events with the status COM_IN_PROGRESS and a startdate which is expired,
* then send the email
*/
Map sendEmailDated() {
Timestamp nowDate = UtilDateTime.nowTimestamp()
EntityCondition conditions = EntityCondition.makeCondition([
EntityCondition.makeCondition('statusId', 'COM_IN_PROGRESS'),
EntityCondition.makeCondition(EntityOperator.OR,
'communicationEventTypeId', 'EMAIL_COMMUNICATION',
'communicationEventTypeId', 'AUTO_EMAIL_COMM'),
EntityCondition.makeCondition([
EntityCondition.makeCondition('datetimeStarted', EntityOperator.LESS_THAN, nowDate),
EntityCondition.makeCondition('datetimeStarted', EntityOperator.EQUALS, null),
], EntityOperator.OR)
])
Map serviceContext = dispatcher.getDispatchContext().makeValidContext('sendCommEventAsEmail', ModelService.IN_PARAM, parameters)
List<GenericValue> communicationEvents = from('CommunicationEvent').where(conditions).queryList()
communicationEvents.each { communicationEvent ->
// run service don't cover the new transaction need
serviceContext.communicationEventId = communicationEvent.communicationEventId
dispatcher.runSync('sendCommEventAsEmail', serviceContext, 7200, true)
}
// sending of internal notes of a contactlist
conditions = EntityCondition.makeCondition([
EntityCondition.makeCondition('communicationEventTypeId', 'COMMENT_NOTE'),
EntityCondition.makeCondition('contactListId', EntityOperator.NOT_EQUAL, null),
EntityCondition.makeCondition('statusId', 'COM_IN_PROGRESS'),
EntityCondition.makeCondition([
EntityCondition.makeCondition('datetimeStarted', EntityOperator.LESS_THAN, nowDate),
EntityCondition.makeCondition('datetimeStarted', EntityOperator.EQUALS, null),
], EntityOperator.OR)
])
communicationEvents = from('CommunicationEvent').where(conditions).queryList()
communicationEvents.each { communicationEvent ->
List<GenericValue> contactListParties = from('ContactListParty')
.where(contactListId: communicationEvent.contactListId)
.queryList()
contactListParties.each { contactListParty ->
Map communicationEventRole = [communicationEventId: communicationEvent.communicationEventId,
roleTypeId: 'ADDRESSEE',
partyId: contactListParty.partyId]
run service: 'createCommunicationEventRole', with: communicationEventRole
}
Map updCommEventStatusMap = [*:communicationEvent]
updCommEventStatusMap.statusId = 'COM_COMPLETE'
run service: 'setCommunicationEventStatus', with: updCommEventStatusMap
}
return success()
}
/**
* Set The Communication Event Status
*/
Map setCommunicationEventStatus() {
GenericValue communicationEvent = from('CommunicationEvent')
.where(parameters)
.queryOne()
oldStatusId = communicationEvent.statusId
if (parameters.statusId != communicationEvent.statusId) {
GenericValue statusChange = from('StatusValidChange')
.where(statusId: communicationEvent.statusId,
statusIdTo: parameters.statusId)
.queryOne()
if (!statusChange) {
logError("Cannot change from ${communicationEventRole.statusId} to ${parameters.statusId}")
return error(UtilProperties.getMessage('ProductUiLabels',
'commeventservices.communication_event_status', parameters.locale as Locale))
}
communicationEvent.statusId = parameters.statusId
communicationEvent.store()
if (parameters.statusId == 'COM_COMPLETE') {
if (parameters.setRoleStatusToComplete == 'Y') {
//if the status of the communicationevent is set to complete, all roles need to be set to complete,
//which means the commevent was dealt with and no further action is required by any
// of the other participants/addressees
List<GenericValue> roles = communicationEvent.getRelated('CommunicationEventRole', null, null, false)
roles.each { role ->
if ('COM_ROLE_COMPLETED' != role.statusId) {
role.statusId = 'COM_ROLE_COMPLETED'
role.store()
}
}
}
} else { //make sure at least the senders role is set to complete
GenericValue communicationEventRole =
from('CommunicationEventRole').where(
communicationEventId: communicationEvent.communicationEventId,
partyId: communicationEvent.partyIdFrom,
roleTypeId: 'ORIGINATOR')
.queryOne()
//found a mispelling in minilang so ...
if (communicationEventRole
&& 'COM_ROLE_COMPLETED' != communicationEventRole.statusId) {
Map updateRoleMap = [*:communicationEventRole]
updateRoleMap.statusId = 'COM_ROLE_COMPLETED'
run service: 'updateCommunicationEventRole', with: updateRoleMap
}
}
}
return success()
}
//set the status for a particular party role to the status COM_ROLE_READ
Map setCommEventRoleToRead() {
parameters.partyId = parameters.partyId ?: parameters.userLogin.partyId
GenericValue eventRole
if (parameters.roleTypeId) {
eventRole = from('CommunicationEventRole')
.where(parameters)
.queryOne()
} else {
eventRole = from('CommunicationEventRole')
.where(communicationEventId: parameters.communicationEventId,
partyId: parameters.partyId)
.queryFirst()
parameters.roleTypeId = eventRole.roleTypeId
}
if (eventRole
&& eventRole.statusId == 'COM_ROLE_CREATED') {
GenericValue userLogin = from('UserLogin').where(userLoginId: 'system').queryOne()
Map updStatMap = [*:parameters]
updStatMap.statusId = 'COM_ROLE_READ'
updStatMap.userLogin = userLogin
run service: 'setCommunicationEventRoleStatus', with: updStatMap
}
return success()
}
//Set The Communication Event Status for a specific role
Map setCommunicationEventRoleStatus() {
GenericValue communicationEventRole = from('CommunicationEventRole')
.where(parameters)
.queryOne()
oldStatusId = communicationEventRole.statusId
if (parameters.statusId != communicationEventRole.statusId) {
GenericValue statusChange = from('StatusValidChange')
.where(statusId: communicationEventRole.statusId,
statusIdTo: parameters.statusId)
.cache()
.queryOne()
if (!statusChange) {
logError("Cannot change from ${communicationEventRole.statusId} to ${parameters.statusId}")
return error(UtilProperties.getMessage('ProductUiLabels',
'commeventservices.communication_event_status', parameters.locale as Locale))
}
communicationEventRole.statusId = parameters.statusId
communicationEventRole.store()
}
return success()
}
//Create communication event and send mail to company
Map sendContactUsEmailToCompany() {
GenericValue systemUserLogin = from('UserLogin').where('userLoginId', 'system').cache().queryOne()
Map contactUsMap = [*:parameters]
contactUsMap.userLogin = systemUserLogin
run service: 'createCommunicationEventWithoutPermission', with: contactUsMap
Map getPartyEmailMap = [partyId: parameters.partyIdTo, userLogin: systemUserLogin]
Map getPartyEmailResult = run service: 'getPartyEmail', with: getPartyEmailMap
GenericValue productStoreEmailSetting = from('ProductStoreEmailSetting')
.where(parameters)
.queryOne()
Map bodyParameters = [partyId: parameters.partyIdTo, email: parameters.emailAddress,
firstName: parameters.firstName, lastName: parameters.lastName,
postalCode: parameters.postalCode, countryCode: parameters.countryCode,
message: parameters.content]
if (productStoreEmailSetting.bodyScreenLocation) {
Map emailParams = [bodyParameters: bodyParameters, userLogin: systemUserLogin]
if (getPartyEmailResult.emailAddress) {
emailParams.sendTo = getPartyEmailResult.emailAddress
} else {
emailParams.sendTo = productStoreEmailSetting.fromAddress
}
emailParams.subject = productStoreEmailSetting.subject
emailParams.sendFrom = productStoreEmailSetting.fromAddress
emailParams.contentType = productStoreEmailSetting.contentType
emailParams.bodyScreenUri = productStoreEmailSetting.bodyScreenLocation
run service: 'sendMailFromScreen', with: emailParams
}
return success()
}