/*
 * 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()
}
