<?xml version="1.0" encoding="UTF-8" ?>
<!--
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.
-->

<simple-methods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://ofbiz.apache.org/Simple-Method" xsi:schemaLocation="http://ofbiz.apache.org/Simple-Method http://ofbiz.apache.org/dtds/simple-methods.xsd">
    <!-- ContactListParty methods -->
    <simple-method method-name="inlineCheckContactListMechType" short-description="inlineCheckContactListMechType">
        <!-- check the preferredContactMechId, make sure it is the right type -->
        <if-not-empty field="parameters.preferredContactMechId">
            <entity-one entity-name="ContactMech" value-field="preferredContactMech" auto-field-map="false">
                <field-map field-name="contactMechId" from-field="parameters.preferredContactMechId"/>
            </entity-one>
            <if-compare-field field="preferredContactMech.contactMechTypeId" to-field="contactList.contactMechTypeId" operator="not-equals">
                <entity-one entity-name="ContactMechType" value-field="preferredContactMechType" auto-field-map="false">
                    <field-map field-name="contactMechTypeId" from-field="preferredContactMech.contactMechTypeId"/>
                </entity-one>
                <entity-one entity-name="ContactMechType" value-field="listContactMechType" auto-field-map="false">
                    <field-map field-name="contactMechTypeId" from-field="contactList.contactMechTypeId"/>
                </entity-one>
                <add-error>
                    <fail-property resource="MarketingUiLabels.xml" property="MarketingContactMechNotRightForContactList"/>
                </add-error>
            </if-compare-field>
        </if-not-empty>
    </simple-method>
    <simple-method method-name="inlineCheckContactListStatusParameter" short-description="inlineCheckContactListMechType">
        <!-- if this is not an email contact list and the status is pending, just set the status to accepted -->
        <if>
            <condition>
                <and>
                    <if-compare field="contactList.contactMechTypeId" operator="not-equals" value="EMAIL_ADDRESS"/>
                    <if-compare field="parameters.statusId" operator="equals" value="CLPT_PENDING"/>
                </and>
            </condition>
            <then>
                <set field="parameters.statusId" value="CLPT_ACCEPTED"/>
            </then>
        </if>
    </simple-method>
    <simple-method method-name="createContactListParty" short-description="Add Party To ContactList">
        <!-- allow if userLogin.partyId = parameters.partyId or has permission -->
        <if>
            <condition>
                <and>
                    <if-compare-field field="userLogin.partyId" to-field="parameters.partyId" operator="not-equals"/>
                    <not><if-has-permission permission="MARKETING" action="_CREATE"/></not>
                </and>
            </condition>
            <then>
                <add-error>
                    <fail-property resource="MarketingUiLabels.xml" property="MarketingCreatePermissionError"/>
                </add-error>
            </then>
        </if>

        <entity-one entity-name="ContactList" value-field="contactList"/>
        <call-simple-method method-name="inlineCheckContactListMechType"/>
        <call-simple-method method-name="inlineCheckContactListStatusParameter"/>

        <!-- okay, now check for all errors -->
        <check-errors/>

        <!-- get party email address if not provided -->
        <if-empty field="parameters.preferredContactMechId">
            <if-empty field="parameters.contactMechId">
                <set field="partyEmail.partyId" from-field="parameters.partyId"/>
                <call-service service-name="getPartyEmail" in-map-name="partyEmail">
                    <result-to-field result-name="contactMechId" field="parameters.preferredContactMechId"/>
                </call-service>        
            </if-empty>
        </if-empty>

        <if-not-empty field="parameters.preferredContactMechId">
            <make-value entity-name="ContactListParty" value-field="newEntity"/>
            <set-nonpk-fields map="parameters" value-field="newEntity"/>
            <set-pk-fields map="parameters" value-field="newEntity"/>
            <if-empty field="newEntity.fromDate"><now-timestamp field="newEntity.fromDate"/></if-empty>

            <create-value value-field="newEntity"/>
            <set-service-fields service-name="createContactListPartyStatus" map="newEntity" to-map="createContactListPartyStatusMap"/>
            <set field="createContactListPartyStatusMap.baseLocation" from-field="parameters.baseLocation"/>
            <call-service service-name="createContactListPartyStatus" in-map-name="createContactListPartyStatusMap"/>

            <!-- Some parties happen to not have email addresses, this should be logged -->
            <else>
                <log level="info" message="Could not find the preferred contact mechanism for party [${parameters.partyId}]"/>
                <set field="partyId" from-field="parameters.partyId"/>
                <property-to-field resource="MarketingUiLabels.xml" property="MarketingContactMechNotExists" field="message"/>
                <field-to-result field="message" result-name="errorMessage"></field-to-result>
            </else>
        </if-not-empty>

    </simple-method>
    <simple-method method-name="updateContactListParty" short-description="Update Add Party To ContactList">
        <!-- allow if userLogin.partyId = parameters.partyId or has permission -->
        <if>
            <condition>
                <and>
                    <if-compare-field field="userLogin.partyId" to-field="parameters.partyId" operator="not-equals"/>
                    <not><if-has-permission permission="MARKETING" action="_UPDATE"/></not>
                </and>
            </condition>
            <then>
                <add-error>
                    <fail-property resource="MarketingUiLabels.xml" property="MarketingUpdatePermissionError"/>
                </add-error>
            </then>
        </if>
        <check-errors/>

        <!--  if fromDate is not found; look up the latest record -->
        <if-empty field="parameters.fromDate">
             <entity-condition entity-name="ContactListPartyStatus" list="lookupList">
                 <condition-list combine="and"> 
                     <condition-expr field-name="contactListId" from-field="parameters.contactListId"/>
                     <condition-expr field-name="partyId" from-field="parameters.partyId"/>
                 </condition-list>
                 <order-by field-name="-statusDate"/>
             </entity-condition>
             <first-from-list list="lookupList" entry="lastRecord"/> 
             <set field="parameters.fromDate" from-field="lastRecord.fromDate"/>             
        </if-empty>
        
        <entity-one entity-name="ContactList" value-field="contactList"/>
        <call-simple-method method-name="inlineCheckContactListMechType"/>
        <call-simple-method method-name="inlineCheckContactListStatusParameter"/>

        <entity-one entity-name="ContactListParty" value-field="lookedUpValue"/>
        <if-not-empty field="parameters.statusId">
            <if-compare-field field="parameters.statusId" to-field="lookedUpValue.statusId" operator="not-equals">
                <!-- NOTE: must be parameters as this will have the new statusId, and it will have additional attributes like optInVerifyCode -->
                <set-service-fields service-name="createContactListPartyStatus" map="parameters" to-map="createContactListPartyStatusMap"/>
                <call-service service-name="createContactListPartyStatus" in-map-name="createContactListPartyStatusMap"/>
            </if-compare-field>
        </if-not-empty>
        <set-nonpk-fields map="parameters" value-field="lookedUpValue"/>
        <store-value value-field="lookedUpValue"/>
        <field-to-result field="parameters.productStoreId" result-name="productStoreId" />
        <field-to-result field="parameters.contactListId" result-name="contactListId" />
    </simple-method>
    <simple-method method-name="updateContactListPartyNoUserLogin" short-description="Update Add Party To ContactList No User Login" login-required="false">
        <entity-one value-field="contactList" entity-name="ContactList"/>
        <entity-and entity-name="ContactListPartyStatus" list="contactListPartyStatusList">
            <field-map field-name="contactListId" from-field="parameters.contactListId"/>
            <field-map field-name="partyId" from-field="parameters.partyId"/>
            <field-map field-name="optInVerifyCode" from-field="parameters.optInVerifyCode"/>
            <field-map field-name="fromDate" from-field="parameters.fromDate"/>
        </entity-and>
        <if-not-empty field="contactListPartyStatusList">
            <set-service-fields service-name="updateContactListParty" map="parameters" to-map="updateContactListPartyMap"/>
            <entity-one entity-name="UserLogin" value-field="systemUserLogin">
                <field-map field-name="userLoginId" value="system"/>
            </entity-one>
            <set field="updateContactListPartyMap.userLogin" from-field="systemUserLogin"/>
            <set field="updateContactListPartyMap.baseLocation" from-field="parameters.baseLocation"/>
            <call-service service-name="updateContactListParty" in-map-name="updateContactListPartyMap"/>
            <else>
                <add-error><fail-message message="Invalid verify code for the ${contactList.contactListName}"/></add-error>
                <check-errors/>
            </else>
        </if-not-empty>
    </simple-method>
    <simple-method method-name="unsubscribeContactListParty" short-description="Unsubscribe for contact list" login-required="false">
        <!-- check valid email -->
        <call-class-method method-name="isEmail" class-name="org.apache.ofbiz.base.util.UtilValidate" ret-field="isEmail">
            <field field="parameters.email"/>
        </call-class-method>
        <if-compare operator="equals" value="false" field="isEmail" type="Boolean">
            <add-error><fail-property resource="MarketingUiLabels" property="MarketingCampaignInvalidEmailInput"/></add-error>
            <check-errors/>
        </if-compare>
        
        <entity-one entity-name="UserLogin" value-field="userLogin">
            <field-map field-name="userLoginId" value="system"/>
        </entity-one>
        <if-empty field="parameters.partyId">
            <set field="parameters.partyId" value="_NA_"/>
        </if-empty>
        <entity-and entity-name="PartyContactWithPurpose" list="partyContactWithPurposes">
            <field-map field-name="partyId" from-field="parameters.partyId"/>
            <field-map field-name="infoString" from-field="parameters.email"/>
            <field-map field-name="contactMechTypeId" value="EMAIL_ADDRESS"/>
            <field-map field-name="contactMechPurposeTypeId" value="OTHER_EMAIL"/>
        </entity-and>
        <filter-list-by-date list="partyContactWithPurposes" from-field-name="contactFromDate" thru-field-name="contactThruDate"/>
        <filter-list-by-date list="partyContactWithPurposes" from-field-name="purposeFromDate" thru-field-name="purposeThruDate"/>
        <!-- if there is email contact mech for party then update contact list party's status to CLPT_UNSUBS_PENDING -->
        <if-not-empty field="partyContactWithPurposes">
            <set field="updateContactListPartyMap.contactListId" from-field="parameters.contactListId"/>
            <set field="updateContactListPartyMap.partyId" from-field="parameters.partyId"/>
            <set field="updateContactListPartyMap.preferredContactMechId" from-field="partyContactWithPurposes[0].contactMechId"/>
            <set field="updateContactListPartyMap.statusId" value="CLPT_UNSUBS_PENDING"/>
            <set field="updateContactListPartyMap.userLogin" from-field="userLogin"/>
            <set field="updateContactListPartyMap.baseLocation" from-field="parameters.baseLocation"/>
            <call-service service-name="updateContactListParty" in-map-name="updateContactListPartyMap"/>
            <else>
                <entity-and entity-name="PartyContactWithPurpose" list="partyContactWithPurposes">
                    <field-map field-name="infoString" from-field="parameters.email"/>
                    <field-map field-name="contactMechTypeId" value="EMAIL_ADDRESS"/>
                </entity-and>
                <filter-list-by-date list="partyContactWithPurposes" from-field-name="contactFromDate" thru-field-name="contactThruDate"/>
                <filter-list-by-date list="partyContactWithPurposes" from-field-name="purposeFromDate" thru-field-name="purposeThruDate"/>
                <if-not-empty field="partyContactWithPurposes">
                    <set field="updateContactListPartyMap.contactListId" from-field="parameters.contactListId"/>
                    <set field="updateContactListPartyMap.partyId" from-field="partyContactWithPurposes[0].partyId"/>
                    <set field="updateContactListPartyMap.preferredContactMechId" from-field="partyContactWithPurposes[0].contactMechId"/>
                    <set field="updateContactListPartyMap.statusId" value="CLPT_UNSUBS_PENDING"/>
                    <set field="updateContactListPartyMap.userLogin" from-field="userLogin"/>
                    <set field="updateContactListPartyMap.baseLocation" from-field="parameters.baseLocation"/>
                    <call-service service-name="updateContactListParty" in-map-name="updateContactListPartyMap"/>
                    <else>
                        <add-error><fail-message message="The email address (${parameters.email}) does not have the Other Email Address as contact purpose."/></add-error>
                        <check-errors/>
                    </else>
                </if-not-empty>
            </else>
        </if-not-empty>
    </simple-method>
    <simple-method method-name="unsubscribeContactListPartyContachMech" short-description="Find email by contactMechId then call unsubscribeContactListParty service">
        <entity-and entity-name="PartyContactWithPurpose" list="partyContactWithPurposes">
            <field-map field-name="contactMechId" from-field="parameters.preferredContactMechId"/>
            <field-map field-name="partyId" from-field="parameters.partyId"/>
            <field-map field-name="contactMechTypeId" value="EMAIL_ADDRESS"/>
        </entity-and>
        <first-from-list list="partyContactWithPurposes" entry="partyContactWithPurpose"/>
        <set field="email" from-field="partyContactWithPurpose.infoString"/>
        <set-service-fields service-name="unsubscribeContactListParty" map="parameters" to-map="unsubscribeContactListPartyCtx"/>
        <set field="unsubscribeContactListPartyCtx.email" from-field="email"/>
        <call-service service-name="unsubscribeContactListParty" in-map-name="unsubscribeContactListPartyCtx"/>
    </simple-method>
    <simple-method method-name="updatePartyEmailContactListParty" short-description="Update ContactList Party Contact Mech">
        <set field="lookupMap.preferredContactMechId" from-field="parameters.oldContactMechId"/>
        <find-by-and entity-name="ContactListParty" map="lookupMap" list="ContactListParties"/>
        <iterate list="ContactListParties" entry="contactlistparty">
        <set field="contactlistparty.preferredContactMechId" from-field="parameters.contactMechId"/>
        <log level="info" message="Replacing preferredContactMechId: ${parameters.oldContactMechId} of the ContactList: ${contactlistparty.contactListId} with new preferredContactMechId: ${parameters.contactMechId}"/>
        <store-value value-field="contactlistparty"/>
        </iterate>
    </simple-method>
    <simple-method method-name="createContactListPartyStatus" short-description="Create ContactListParty Status">
        <!-- allow if userLogin.partyId = parameters.partyId or has permission -->
        <if>
            <condition>
                <and>
                    <if-compare-field field="userLogin.partyId" to-field="parameters.partyId" operator="not-equals"/>
                    <not><if-has-permission permission="MARKETING" action="_CREATE"/></not>
                    <not><if-has-permission permission="MARKETING" action="_UPDATE"/></not>
                </and>
            </condition>
            <then>
                <add-error>
                    <fail-property resource="MarketingUiLabels.xml" property="MarketingCreatePermissionError"/>
                </add-error>
            </then>
        </if>
        <check-errors/>

        <make-value entity-name="ContactListPartyStatus" value-field="newEntity"/>                
        <set-pk-fields map="parameters" value-field="newEntity"/>
        <set-nonpk-fields map="parameters" value-field="newEntity"/>
        
        <now-timestamp field="newEntity.statusDate"/>
        <set from-field="userLogin.userLoginId" field="newEntity.setByUserLoginId"/>

        <!-- if statusId is CLPT_PENDING, set optInVerifyCode; else if statusId is CLPT_ACCEPTED, make sure optInVerifyCode is the same as the last CLPT_PENDING -->
        <if>
            <condition><if-compare field="newEntity.statusId" operator="equals" value="CLPT_PENDING"/></condition>
            <then>
                <script>groovy:newEntity.set("optInVerifyCode", Long.toString(Math.round(9999999999L * Math.random())))</script>
            </then>
        <else-if>
            <condition><if-compare field="newEntity.statusId" operator="equals" value="CLPT_ACCEPTED"/></condition>
            <then>
                <!-- look up the last ContactListPartyStatus with statusId=CLPT_PENDING -->
                <entity-condition entity-name="ContactListPartyStatus" list="lastContactListPartyStatusList">
                    <condition-list combine="and">
                        <condition-expr field-name="contactListId" from-field="parameters.contactListId"/>
                        <condition-expr field-name="partyId" from-field="parameters.partyId"/>
                        <condition-expr field-name="fromDate" from-field="parameters.fromDate"/>
                        <condition-expr field-name="statusId" value="CLPT_PENDING"/>
                    </condition-list>
                    <order-by field-name="-statusDate"/>
                </entity-condition>
                <first-from-list list="lastContactListPartyStatusList" entry="lastContactListPartyStatus"/>

                <!-- only require an optInVerifyCode if there was one in place -->
                <if-not-empty field="lastContactListPartyStatus.optInVerifyCode">
                    <if-not-empty field="parameters.optInVerifyCode">
                        <if-compare-field field="lastContactListPartyStatus.optInVerifyCode" to-field="parameters.optInVerifyCode" operator="not-equals">
                            <add-error>
                                <fail-property resource="MarketingUiLabels.xml" property="MarketingContactListOptInVerifyCodeNotCorrect"/>
                            </add-error>
                        </if-compare-field>
                    <else>
                        <add-error>
                            <fail-property resource="MarketingUiLabels.xml" property="MarketingContactListOptInVerifyCodeIsMandatory"/>
                        </add-error>
                    </else>
                    </if-not-empty>
                </if-not-empty>
                <check-errors/>
            </then>
        </else-if>
        </if>
                
        <create-value value-field="newEntity"/>
    </simple-method>

    <simple-method method-name="sendContactListPartyVerifyEmail" short-description="Send ContactListParty Verify Email">
        <!-- allow if userLogin.partyId = parameters.partyId or has permission -->
        <if>
            <condition>
                <and>
                    <if-compare-field field="userLogin.partyId" to-field="parameters.partyId" operator="not-equals"/>
                    <not><if-has-permission permission="MARKETING" action="_VIEW"/></not>
                </and>
            </condition>
            <then>
                <add-error>
                    <fail-property resource="MarketingUiLabels.xml" property="MarketingViewPermissionError"/>
                </add-error>
            </then>
        </if>
        <check-errors/>

        <entity-one entity-name="ContactList" value-field="contactList"/>
        <entity-one entity-name="ContactListParty" value-field="contactListParty"/>
        <get-related-one value-field="contactListParty" relation-name="PreferredContactMech" to-value-field="preferredContactMech"/>

        <if>
            <condition>
                <and>
                    <not><if-empty field="contactList.verifyEmailFrom"></if-empty></not>
                    <not><if-empty field="contactList.verifyEmailSubject"></if-empty></not>
                    <not><if-empty field="contactList.verifyEmailScreen"></if-empty></not>
                    <not><if-empty field="contactList.verifyEmailWebSiteId"></if-empty></not>
                </and>
            </condition>
            <then>
                <!-- get the latest pending status -->
                <!-- look up the last ContactListPartyStatus with statusId=CLPT_PENDING -->
                <entity-condition entity-name="ContactListPartyStatus" list="lastContactListPartyStatusList">
                    <condition-list combine="and">
                        <condition-expr field-name="contactListId" from-field="parameters.contactListId"/>
                        <condition-expr field-name="partyId" from-field="parameters.partyId"/>
                        <condition-expr field-name="fromDate" from-field="parameters.fromDate"/>
                        <condition-expr field-name="statusId" value="CLPT_PENDING"/>
                    </condition-list>
                    <order-by field-name="-statusDate"/>
                </entity-condition>
                <first-from-list list="lastContactListPartyStatusList" entry="contactListPartyStatus"/>

                <!-- TODO: if preferredContactMech.contactMechTypeId != EMAIL_ADDRESS, return an error -->
                <!-- TODO: if preferredContactMech is empty, should we try to find the ContactMech we want based on the Party? -->

                <!-- TODO: this could really use some more work to be more flexible, or easier to maintain, like perhaps a general EmailSendSettings entity or something -->
                <set from-field="preferredContactMech.infoString" field="sendMailFromScreenMap.sendTo"/>
                <set from-field="contactList.verifyEmailFrom" field="sendMailFromScreenMap.sendFrom"/>
                <set from-field="contactList.verifyEmailSubject" field="sendMailFromScreenMap.subject"/>
                <set from-field="contactList.verifyEmailScreen" field="sendMailFromScreenMap.bodyScreenUri"/>
                <set from-field="contactList.verifyEmailWebSiteId" field="sendMailFromScreenMap.webSiteId"/>
                <set value="text/html" field="sendMailFromScreenMap.contentType"/>

                <set from-field="contactList" field="sendMailFromScreenMap.bodyParameters.contactList"/>
                <set from-field="contactListParty" field="sendMailFromScreenMap.bodyParameters.contactListParty"/>
                <set from-field="contactListPartyStatus" field="sendMailFromScreenMap.bodyParameters.contactListPartyStatus"/>
                <set from-field="parameters.baseLocation" field="sendMailFromScreenMap.bodyParameters.baseLocation"/>
                
                <call-service service-name="sendMailFromScreen" in-map-name="sendMailFromScreenMap"/>
            </then>
            <else>
                <log level="warning" message="WARNING: Not sending subscription verify email because verifyEmail* settings are missing on the ContactList record: ${contactList}"/>
            </else>
        </if>
    </simple-method>
    <simple-method method-name="createWebSiteContactList" short-description="Add WebSite ContactList">
        <entity-and entity-name="WebSiteContactList" list="webSiteContactList">
            <field-map field-name="webSiteId" from-field="parameters.webSiteId"/>
            <field-map field-name="contactListId" from-field="parameters.contactListId"/>
            <field-map field-name="fromDate" from-field="parameters.fromDate"/>
        </entity-and>
        <if-empty field="webSiteContactList">
            <make-value entity-name="WebSiteContactList" value-field="webSiteContactList"/>
            <set-pk-fields value-field="webSiteContactList" map="parameters"/>
            <set-nonpk-fields map="parameters" value-field="webSiteContactList"/>
            <create-value value-field="webSiteContactList"/>
            <return/>
        </if-empty>
        <set field="message" value="This webSiteContactList (webSiteId[${parameters.webSiteId}], contactListId[${parameters.contactListId}]) already exists."/>
        <field-to-result field="message" result-name="errorMessage"></field-to-result>
    </simple-method>
    <simple-method method-name="updateWebSiteContactList" short-description="Update WebSite ContactList">
        <entity-and entity-name="WebSiteContactList" list="webSiteContactList">
            <field-map field-name="webSiteId" from-field="parameters.webSiteId"/>
            <field-map field-name="contactListId" from-field="parameters.contactListId"/>
            <field-map field-name="fromDate" from-field="parameters.fromDate"/>
        </entity-and>
        <first-from-list list="webSiteContactList" entry="entryWebSiteContactList"/>
        <set-pk-fields value-field="entryWebSiteContactList" map="parameters"/>
        <set-nonpk-fields map="parameters" value-field="entryWebSiteContactList"/>
        <store-value value-field="entryWebSiteContactList"/>
    </simple-method>
    <simple-method method-name="deleteWebSiteContactList" short-description="Delete WebSite ContactList">
        <entity-and entity-name="WebSiteContactList" list="webSiteContactList">
            <field-map field-name="webSiteId" from-field="parameters.webSiteId"/>
            <field-map field-name="contactListId" from-field="parameters.contactListId"/>
            <field-map field-name="fromDate" from-field="parameters.fromDate"/>
        </entity-and>
        <remove-list list="webSiteContactList"/>
    </simple-method>
    
    <!-- service to use in contact list communications to handle opt-out links based on the communication event sent -->
    <simple-method method-name="optOutOfListFromCommEvent" short-description="Contact List Opt Out From Communication Event" login-required="false">
        <entity-one entity-name="CommunicationEvent" value-field="commEvent"/>
        <if>
            <condition>
                <and>                    
                    <not><if-empty field="commEvent"/></not>
                    <not><if-empty field="commEvent.contactListId"/></not>
                    <not><if-empty field="commEvent.partyIdTo"/></not>
                    <not><if-empty field="commEvent.contactMechIdTo"/></not>
                </and>
            </condition>
            <then>
                <now-timestamp field="nowTimestamp"/>
                <entity-and entity-name="ContactListParty" list="contactListPartyList">
                    <field-map field-name="contactListId" from-field="commEvent.contactListId"/>
                    <field-map field-name="preferredContactMechId" from-field="commEvent.contactMechIdTo"/>
                    <field-map field-name="partyId" from-field="commEvent.partyIdTo"/>                    
                </entity-and>
                <filter-list-by-date list="contactListPartyList"/>
                <iterate list="contactListPartyList" entry="contactListParty">
                    <set field="contactListParty.thruDate" from-field="nowTimestamp"/>
                    <store-value value-field="contactListParty"/>
                </iterate>                                
            </then>
        </if>
        <field-to-result field="commEvent.contactListId" result-name="contactListId"/>        
    </simple-method>
    
    <simple-method method-name="updateContactListCommStatus" short-description="Update ContactList Communication Status">        
        <entity-one entity-name="ContactListCommStatus" value-field="lookedUpValue" auto-field-map="true"/>
        <if-empty field="lookedUpValue">
             <make-value entity-name="ContactListCommStatus" value-field="lookedUpValue"/>
             <set-pk-fields map="parameters" value-field="lookedUpValue"/>
             <set-nonpk-fields map="parameters" value-field="lookedUpValue"/>
             <set field="lookedUpValue.changeByUserLoginId" from-field="userLogin.userLoginId"/>
             <create-value value-field="lookedUpValue"/>
             <else>
                 <set-nonpk-fields map="parameters" value-field="lookedUpValue"/>
                 <set field="lookedUpValue.changeByUserLoginId" from-field="userLogin.userLoginId"/>
                 <store-value value-field="lookedUpValue"/> 
             </else>
        </if-empty>                 
    </simple-method>
    
    <simple-method method-name="updateCommStatusFromCommEvent" short-description="Update ContactList Comm Status from CommunicationEvent">
        <entity-one entity-name="CommunicationEvent" value-field="commEvent"/> 
        <if-not-empty field="commEvent">
            <entity-and entity-name="ContactListCommStatus" list="clcs">
                <field-map field-name="communicationEventId" from-field="commEvent.parentCommEventId"/>
                <field-map field-name="partyId" from-field="commEvent.partyIdTo"/>
                <field-map field-name="contactMechId" from-field="commEvent.contactMechIdTo"/>
            </entity-and>
            <iterate list="clcs" entry="commStatus">
                <set-service-fields service-name="updateContactListCommStatus" to-map="updateStatusCtx" map="commStatus"/>
                <set field="updateStatusCtx.statusId" from-field="parameters.statusId"/>
                <call-service service-name="updateContactListCommStatus" in-map-name="updateStatusCtx"/>
            </iterate>
        </if-not-empty>                                       
    </simple-method>       
    
    <simple-method method-name="sendContactListPartySubscribeEmail" short-description="Send contact list party subscribe email" login-required="true">
        <set field="productStoreId" type="String" from-field="parameters.productStoreId"/>
        <entity-one entity-name="ContactList" value-field="contactList"/>
        <entity-one entity-name="ContactListParty" value-field="contactListParty"/>
        <!-- get the latest accepted status -->
        <!-- look up the last ContactListPartyStatus with statusId=CLPT_ACCEPTED -->
        <entity-condition entity-name="ContactListPartyStatus" list="lastContactListPartyStatusList">
            <condition-list combine="and">
                <condition-expr field-name="contactListId" from-field="parameters.contactListId"/>
                <condition-expr field-name="partyId" from-field="parameters.partyId"/>
                <condition-expr field-name="fromDate" from-field="parameters.fromDate"/>
                <condition-expr field-name="statusId" value="CLPT_ACCEPTED"/>
            </condition-list>
            <order-by field-name="-statusDate"/>
        </entity-condition>
        <first-from-list list="lastContactListPartyStatusList" entry="contactListPartyStatus"/>
                
        <if-empty field="productStoreId">
            <entity-one entity-name="WebSite" value-field="webSite">
                <field-map field-name="webSiteId" from-field="contactList.verifyEmailWebSiteId"/>
            </entity-one>
            <set field="productStoreId" from-field="webSite.productStoreId"/>
        </if-empty>
        <entity-one entity-name="ProductStoreEmailSetting" value-field="storeEmail" auto-field-map="false">
            <field-map field-name="productStoreId" from-field="productStoreId"/>
            <field-map field-name="emailType" value="SUB_CONT_LIST_NOTI"/>
        </entity-one>
        <entity-one entity-name="ContactMech" value-field="contactMech" auto-field-map="false">
            <field-map field-name="contactMechId" from-field="parameters.preferredContactMechId"/>
        </entity-one>
        <if-not-empty field="storeEmail.bodyScreenLocation">
            <!-- send email from screen -->
            <set field="bodyParameters.contactListId" from-field="parameters.contactListId"/>
            <set field="bodyParameters.partyId" from-field="parameters.partyId"/>
            <set field="bodyParameters.contactList" from-field="contactList"/>
            <set field="bodyParameters.contactListParty" from-field="contactListParty"/>
            <set field="bodyParameters.contactListPartyStatus" from-field="contactListPartyStatus"/>
            <set field="bodyParameters.baseLocation" from-field="parameters.baseLocation"/>
            
            <set field="emailParams.bodyParameters" from-field="bodyParameters"/>
            <set field="emailParams.userLogin" from-field="userLogin"/>
            <set field="emailParams.webSiteId" from-field="contactList.verifyEmailWebSiteId"/>
            <set field="emailParams.sendTo" from-field="contactMech.infoString"/>
            <set field="emailParams.sendFrom" from-field="storeEmail.fromAddress"/>
            <set field="emailParams.subject" value="${storeEmail.subject} ${contactList.contactListName}"/>
            <set field="emailParams.bodyScreenUri" from-field="storeEmail.bodyScreenLocation"/>
            <set field="emailParams.contentType" value="text/html"/>
            <call-service service-name="sendMailFromScreen" in-map-name="emailParams"/>
        </if-not-empty>
    </simple-method>
    
    <simple-method method-name="sendContactListPartyUnSubscribeVerifyEmail" short-description="Send contact list party unsubscribe verify email" login-required="true">
        <if>
            <condition>
                <and>
                    <not><if-has-permission permission="MARKETING" action="_VIEW"/></not>
                </and>
            </condition>
            <then><add-error><fail-message message="Security Error: to run sendContactListPartyVerifyEmail you must have the MARKETING_VIEW or MARKETING_ADMIN permissions."/></add-error></then>
        </if>
        <check-errors/>

        <entity-one entity-name="ContactList" value-field="contactList"/>
        <entity-one entity-name="ContactListParty" value-field="contactListParty"/>
        <get-related-one value-field="contactListParty" relation-name="PreferredContactMech" to-value-field="preferredContactMech"/>
        
        <!-- get the latest accepted status -->
        <!-- look up the last ContactListPartyStatus with statusId=CLPT_ACCEPTED -->
        <entity-condition entity-name="ContactListPartyStatus" list="lastContactListPartyStatusList">
            <condition-list combine="and">
                <condition-expr field-name="contactListId" from-field="parameters.contactListId"/>
                <condition-expr field-name="partyId" from-field="parameters.partyId"/>
                <condition-expr field-name="fromDate" from-field="parameters.fromDate"/>
                <condition-expr field-name="statusId" value="CLPT_ACCEPTED"/>
            </condition-list>
            <order-by field-name="-statusDate"/>
        </entity-condition>
        <first-from-list list="lastContactListPartyStatusList" entry="contactListPartyStatus"/>
        
        <set field="productStoreId" type="String" from-field="parameters.productStoreId"/>
        <entity-one entity-name="ContactList" value-field="contactList"/>
        <if-empty field="productStoreId">
            <entity-one entity-name="WebSite" value-field="webSite">
                <field-map field-name="webSiteId" from-field="contactList.verifyEmailWebSiteId"/>
            </entity-one>
            <set field="productStoreId" from-field="webSite.productStoreId"/>
        </if-empty>
        <entity-one entity-name="ProductStoreEmailSetting" value-field="storeEmail" auto-field-map="false">
            <field-map field-name="productStoreId" from-field="productStoreId"/>
            <field-map field-name="emailType" value="UNSUB_CONT_LIST_VERI"/>
        </entity-one>
        <entity-one entity-name="ContactMech" value-field="contactMech" auto-field-map="false">
            <field-map field-name="contactMechId" from-field="parameters.preferredContactMechId"/>
        </entity-one>
        <if-not-empty field="storeEmail.bodyScreenLocation">
            <!-- create communication event -->
            <set field="createCommunicationEventInMap.contactListId" from-field="contactList.contactListId"/>
            <set field="createCommunicationEventInMap.partyIdTo" from-field="contactListParty.partyId"/>
            <set field="createCommunicationEventInMap.contactMechIdTo" from-field="contactListParty.preferredContactMechId"/>
            <set field="createCommunicationEventInMap.fromString" from-field="storeEmail.fromAddress"/>
            <set field="createCommunicationEventInMap.toString" from-field="contactMech.infoString"/>
            <set field="createCommunicationEventInMap.userLogin" from-field="contactMech.userLogin"/>
            <set field="createCommunicationEventInMap.subject" value="${storeEmail.subject} ${contactList.contactListName}"/>
            <call-service service-name="createCommunicationEvent" in-map-name="createCommunicationEventInMap">
                <result-to-field result-name="communicationEventId"/>
            </call-service>
            
            <!-- send email from screen -->
            <set field="bodyParameters.contactListId" from-field="parameters.contactListId"/>
            <set field="bodyParameters.partyId" from-field="parameters.partyId"/>
            <set field="bodyParameters.contactList" from-field="contactList"/>
            <set field="bodyParameters.contactListParty" from-field="contactListParty"/>
            <set field="bodyParameters.contactListPartyStatus" from-field="contactListPartyStatus"/>
            <set field="bodyParameters.baseLocation" from-field="parameters.baseLocation"/>
            
            <set field="emailParams.webSiteId" from-field="contactList.verifyEmailWebSiteId"/>
            <set field="emailParams.bodyParameters" from-field="bodyParameters"/>
            <set field="emailParams.communicationEventId" from-field="communicationEventId"/>
            <set field="emailParams.userLogin" from-field="userLogin"/>
            <set field="emailParams.sendTo" from-field="contactMech.infoString"/>
            <set field="emailParams.sendFrom" from-field="storeEmail.fromAddress"/>
            <set field="emailParams.subject" value="${storeEmail.subject} ${contactList.contactListName}"/>
            <set field="emailParams.bodyScreenUri" from-field="storeEmail.bodyScreenLocation"/>
            <set field="emailParams.contentType" value="text/html"/>
            <call-service service-name="sendMailFromScreen" in-map-name="emailParams"/>
        </if-not-empty>
    </simple-method>
    <simple-method method-name="sendContactListPartyUnSubscribeEmail" short-description="Send contact list party unsubscribe email" login-required="true">
        <set field="productStoreId" type="String" from-field="parameters.productStoreId"/>
        <entity-one entity-name="ContactList" value-field="contactList"/>
        <if-empty field="productStoreId">
            <entity-one entity-name="WebSite" value-field="webSite">
                <field-map field-name="webSiteId" from-field="contactList.verifyEmailWebSiteId"/>
            </entity-one>
            <set field="productStoreId" from-field="webSite.productStoreId"/>
        </if-empty>
        <entity-one entity-name="ProductStoreEmailSetting" value-field="storeEmail" auto-field-map="false">
            <field-map field-name="productStoreId" from-field="productStoreId"/>
            <field-map field-name="emailType" value="UNSUB_CONT_LIST_NOTI"/>
        </entity-one>
        <entity-one entity-name="ContactMech" value-field="contactMech" auto-field-map="false">
            <field-map field-name="contactMechId" from-field="parameters.preferredContactMechId"/>
        </entity-one>
        <if-not-empty field="storeEmail.bodyScreenLocation">
            <set field="bodyParameters.contactListId" from-field="parameters.contactListId"/>
            <set field="bodyParameters.partyId" from-field="parameters.partyId"/>
            <set field="emailParams.webSiteId" from-field="contactList.verifyEmailWebSiteId"/>
            <set field="emailParams.bodyParameters" from-field="bodyParameters"/>
            <set field="emailParams.userLogin" from-field="userLogin"/>
            <set field="emailParams.sendTo" from-field="contactMech.infoString"/>
            <set field="emailParams.sendFrom" from-field="storeEmail.fromAddress"/>
            <set field="emailParams.subject" value="${storeEmail.subject} ${contactList.contactListName}"/>
            <set field="emailParams.bodyScreenUri" from-field="storeEmail.bodyScreenLocation"/>
            <set field="emailParams.contentType" value="text/html"/>
            <call-service service-name="sendMailFromScreen" in-map-name="emailParams"/>
        </if-not-empty>
    </simple-method>
</simple-methods>
