001// --------------------------------------------------------------------------------
002// Copyright 2002-2024 Echo Three, LLC
003//
004// Licensed under the Apache License, Version 2.0 (the "License");
005// you may not use this file except in compliance with the License.
006// You may obtain a copy of the License at
007//
008//     http://www.apache.org/licenses/LICENSE-2.0
009//
010// Unless required by applicable law or agreed to in writing, software
011// distributed under the License is distributed on an "AS IS" BASIS,
012// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013// See the License for the specific language governing permissions and
014// limitations under the License.
015// --------------------------------------------------------------------------------
016
017package com.echothree.model.control.contactlist.server;
018
019import com.echothree.model.control.contact.server.control.ContactControl;
020import com.echothree.model.control.contactlist.common.choice.ContactListChoicesBean;
021import com.echothree.model.control.contactlist.common.choice.ContactListContactMechanismPurposeChoicesBean;
022import com.echothree.model.control.contactlist.common.choice.ContactListFrequencyChoicesBean;
023import com.echothree.model.control.contactlist.common.choice.ContactListGroupChoicesBean;
024import com.echothree.model.control.contactlist.common.choice.ContactListTypeChoicesBean;
025import com.echothree.model.control.contactlist.common.choice.PartyContactListStatusChoicesBean;
026import com.echothree.model.control.contactlist.common.transfer.ContactListContactMechanismPurposeTransfer;
027import com.echothree.model.control.contactlist.common.transfer.ContactListDescriptionTransfer;
028import com.echothree.model.control.contactlist.common.transfer.ContactListFrequencyDescriptionTransfer;
029import com.echothree.model.control.contactlist.common.transfer.ContactListFrequencyTransfer;
030import com.echothree.model.control.contactlist.common.transfer.ContactListGroupDescriptionTransfer;
031import com.echothree.model.control.contactlist.common.transfer.ContactListGroupTransfer;
032import com.echothree.model.control.contactlist.common.transfer.ContactListTransfer;
033import com.echothree.model.control.contactlist.common.transfer.ContactListTypeDescriptionTransfer;
034import com.echothree.model.control.contactlist.common.transfer.ContactListTypeTransfer;
035import com.echothree.model.control.contactlist.common.transfer.CustomerTypeContactListGroupTransfer;
036import com.echothree.model.control.contactlist.common.transfer.CustomerTypeContactListTransfer;
037import com.echothree.model.control.contactlist.common.transfer.PartyContactListTransfer;
038import com.echothree.model.control.contactlist.common.transfer.PartyTypeContactListGroupTransfer;
039import com.echothree.model.control.contactlist.common.transfer.PartyTypeContactListTransfer;
040import com.echothree.model.control.contactlist.common.workflow.PartyContactListStatusConstants;
041import com.echothree.model.control.contactlist.server.transfer.ContactListContactMechanismPurposeTransferCache;
042import com.echothree.model.control.contactlist.server.transfer.ContactListFrequencyTransferCache;
043import com.echothree.model.control.contactlist.server.transfer.ContactListGroupTransferCache;
044import com.echothree.model.control.contactlist.server.transfer.ContactListTransferCache;
045import com.echothree.model.control.contactlist.server.transfer.ContactListTransferCaches;
046import com.echothree.model.control.contactlist.server.transfer.ContactListTypeTransferCache;
047import com.echothree.model.control.contactlist.server.transfer.CustomerTypeContactListGroupTransferCache;
048import com.echothree.model.control.contactlist.server.transfer.CustomerTypeContactListTransferCache;
049import com.echothree.model.control.contactlist.server.transfer.PartyContactListTransferCache;
050import com.echothree.model.control.contactlist.server.transfer.PartyTypeContactListGroupTransferCache;
051import com.echothree.model.control.contactlist.server.transfer.PartyTypeContactListTransferCache;
052import com.echothree.model.control.core.common.EventTypes;
053import com.echothree.model.control.letter.server.control.LetterControl;
054import com.echothree.model.data.chain.common.pk.ChainPK;
055import com.echothree.model.data.chain.server.entity.Chain;
056import com.echothree.model.data.contact.common.pk.ContactMechanismPurposePK;
057import com.echothree.model.data.contact.server.entity.ContactMechanismPurpose;
058import com.echothree.model.data.contactlist.common.pk.ContactListContactMechanismPurposePK;
059import com.echothree.model.data.contactlist.common.pk.ContactListFrequencyPK;
060import com.echothree.model.data.contactlist.common.pk.ContactListGroupPK;
061import com.echothree.model.data.contactlist.common.pk.ContactListPK;
062import com.echothree.model.data.contactlist.common.pk.ContactListTypePK;
063import com.echothree.model.data.contactlist.common.pk.PartyContactListPK;
064import com.echothree.model.data.contactlist.server.entity.ContactList;
065import com.echothree.model.data.contactlist.server.entity.ContactListContactMechanismPurpose;
066import com.echothree.model.data.contactlist.server.entity.ContactListContactMechanismPurposeDetail;
067import com.echothree.model.data.contactlist.server.entity.ContactListDescription;
068import com.echothree.model.data.contactlist.server.entity.ContactListDetail;
069import com.echothree.model.data.contactlist.server.entity.ContactListFrequency;
070import com.echothree.model.data.contactlist.server.entity.ContactListFrequencyDescription;
071import com.echothree.model.data.contactlist.server.entity.ContactListFrequencyDetail;
072import com.echothree.model.data.contactlist.server.entity.ContactListGroup;
073import com.echothree.model.data.contactlist.server.entity.ContactListGroupDescription;
074import com.echothree.model.data.contactlist.server.entity.ContactListGroupDetail;
075import com.echothree.model.data.contactlist.server.entity.ContactListType;
076import com.echothree.model.data.contactlist.server.entity.ContactListTypeDescription;
077import com.echothree.model.data.contactlist.server.entity.ContactListTypeDetail;
078import com.echothree.model.data.contactlist.server.entity.CustomerTypeContactList;
079import com.echothree.model.data.contactlist.server.entity.CustomerTypeContactListGroup;
080import com.echothree.model.data.contactlist.server.entity.PartyContactList;
081import com.echothree.model.data.contactlist.server.entity.PartyContactListDetail;
082import com.echothree.model.data.contactlist.server.entity.PartyTypeContactList;
083import com.echothree.model.data.contactlist.server.entity.PartyTypeContactListGroup;
084import com.echothree.model.data.contactlist.server.factory.ContactListContactMechanismPurposeDetailFactory;
085import com.echothree.model.data.contactlist.server.factory.ContactListContactMechanismPurposeFactory;
086import com.echothree.model.data.contactlist.server.factory.ContactListDescriptionFactory;
087import com.echothree.model.data.contactlist.server.factory.ContactListDetailFactory;
088import com.echothree.model.data.contactlist.server.factory.ContactListFactory;
089import com.echothree.model.data.contactlist.server.factory.ContactListFrequencyDescriptionFactory;
090import com.echothree.model.data.contactlist.server.factory.ContactListFrequencyDetailFactory;
091import com.echothree.model.data.contactlist.server.factory.ContactListFrequencyFactory;
092import com.echothree.model.data.contactlist.server.factory.ContactListGroupDescriptionFactory;
093import com.echothree.model.data.contactlist.server.factory.ContactListGroupDetailFactory;
094import com.echothree.model.data.contactlist.server.factory.ContactListGroupFactory;
095import com.echothree.model.data.contactlist.server.factory.ContactListTypeDescriptionFactory;
096import com.echothree.model.data.contactlist.server.factory.ContactListTypeDetailFactory;
097import com.echothree.model.data.contactlist.server.factory.ContactListTypeFactory;
098import com.echothree.model.data.contactlist.server.factory.CustomerTypeContactListFactory;
099import com.echothree.model.data.contactlist.server.factory.CustomerTypeContactListGroupFactory;
100import com.echothree.model.data.contactlist.server.factory.PartyContactListDetailFactory;
101import com.echothree.model.data.contactlist.server.factory.PartyContactListFactory;
102import com.echothree.model.data.contactlist.server.factory.PartyTypeContactListFactory;
103import com.echothree.model.data.contactlist.server.factory.PartyTypeContactListGroupFactory;
104import com.echothree.model.data.contactlist.server.value.ContactListContactMechanismPurposeDetailValue;
105import com.echothree.model.data.contactlist.server.value.ContactListDescriptionValue;
106import com.echothree.model.data.contactlist.server.value.ContactListDetailValue;
107import com.echothree.model.data.contactlist.server.value.ContactListFrequencyDescriptionValue;
108import com.echothree.model.data.contactlist.server.value.ContactListFrequencyDetailValue;
109import com.echothree.model.data.contactlist.server.value.ContactListGroupDescriptionValue;
110import com.echothree.model.data.contactlist.server.value.ContactListGroupDetailValue;
111import com.echothree.model.data.contactlist.server.value.ContactListTypeDescriptionValue;
112import com.echothree.model.data.contactlist.server.value.ContactListTypeDetailValue;
113import com.echothree.model.data.contactlist.server.value.CustomerTypeContactListGroupValue;
114import com.echothree.model.data.contactlist.server.value.CustomerTypeContactListValue;
115import com.echothree.model.data.contactlist.server.value.PartyContactListDetailValue;
116import com.echothree.model.data.contactlist.server.value.PartyTypeContactListGroupValue;
117import com.echothree.model.data.contactlist.server.value.PartyTypeContactListValue;
118import com.echothree.model.data.core.server.entity.EntityInstance;
119import com.echothree.model.data.customer.common.pk.CustomerTypePK;
120import com.echothree.model.data.customer.server.entity.CustomerType;
121import com.echothree.model.data.party.common.pk.PartyPK;
122import com.echothree.model.data.party.common.pk.PartyTypePK;
123import com.echothree.model.data.party.server.entity.Language;
124import com.echothree.model.data.party.server.entity.Party;
125import com.echothree.model.data.party.server.entity.PartyType;
126import com.echothree.model.data.user.server.entity.UserVisit;
127import com.echothree.model.data.workflow.common.pk.WorkflowEntrancePK;
128import com.echothree.model.data.workflow.server.entity.WorkflowDestination;
129import com.echothree.model.data.workflow.server.entity.WorkflowEntityStatus;
130import com.echothree.model.data.workflow.server.entity.WorkflowEntrance;
131import com.echothree.util.common.message.ExecutionErrors;
132import com.echothree.util.common.persistence.BasePK;
133import com.echothree.util.server.control.BaseModelControl;
134import com.echothree.util.server.message.ExecutionErrorAccumulator;
135import com.echothree.util.server.persistence.EntityPermission;
136import com.echothree.util.server.persistence.Session;
137import java.util.ArrayList;
138import java.util.Collection;
139import java.util.Collections;
140import java.util.HashMap;
141import java.util.Iterator;
142import java.util.List;
143import java.util.Map;
144import java.util.Objects;
145
146public class ContactListControl
147        extends BaseModelControl {
148    
149    /** Creates a new instance of ContactListControl */
150    public ContactListControl() {
151        super();
152    }
153    
154    // --------------------------------------------------------------------------------
155    //   Contact List Transfer Caches
156    // --------------------------------------------------------------------------------
157    
158    private ContactListTransferCaches contactListTransferCaches;
159    
160    public ContactListTransferCaches getContactListTransferCaches(UserVisit userVisit) {
161        if(contactListTransferCaches == null) {
162            contactListTransferCaches = new ContactListTransferCaches(userVisit, this);
163        }
164        
165        return contactListTransferCaches;
166    }
167    
168    // --------------------------------------------------------------------------------
169    //   Contact List Types
170    // --------------------------------------------------------------------------------
171
172    public ContactListType createContactListType(String contactListTypeName, Chain confirmationRequestChain, Chain subscribeChain, Chain unsubscribeChain,
173            Boolean usedForSolicitation, Boolean isDefault, Integer sortOrder, BasePK createdBy) {
174        ContactListType defaultContactListType = getDefaultContactListType();
175        boolean defaultFound = defaultContactListType != null;
176
177        if(defaultFound && isDefault) {
178            ContactListTypeDetailValue defaultContactListTypeDetailValue = getDefaultContactListTypeDetailValueForUpdate();
179
180            defaultContactListTypeDetailValue.setIsDefault(Boolean.FALSE);
181            updateContactListTypeFromValue(defaultContactListTypeDetailValue, false, createdBy);
182        } else if(!defaultFound) {
183            isDefault = Boolean.TRUE;
184        }
185
186        ContactListType contactListType = ContactListTypeFactory.getInstance().create();
187        ContactListTypeDetail contactListTypeDetail = ContactListTypeDetailFactory.getInstance().create(contactListType, contactListTypeName,
188                confirmationRequestChain, subscribeChain, unsubscribeChain, usedForSolicitation, isDefault, sortOrder, session.START_TIME_LONG,
189                Session.MAX_TIME_LONG);
190
191        // Convert to R/W
192        contactListType = ContactListTypeFactory.getInstance().getEntityFromPK(EntityPermission.READ_WRITE,
193                contactListType.getPrimaryKey());
194        contactListType.setActiveDetail(contactListTypeDetail);
195        contactListType.setLastDetail(contactListTypeDetail);
196        contactListType.store();
197
198        sendEvent(contactListType.getPrimaryKey(), EventTypes.CREATE, null, null, createdBy);
199
200        return contactListType;
201    }
202
203    private static final Map<EntityPermission, String> getContactListTypeByNameQueries;
204
205    static {
206        Map<EntityPermission, String> queryMap = new HashMap<>(2);
207
208        queryMap.put(EntityPermission.READ_ONLY,
209                "SELECT _ALL_ "
210                + "FROM contactlisttypes, contactlisttypedetails "
211                + "WHERE clsttyp_activedetailid = clsttypdt_contactlisttypedetailid AND clsttypdt_contactlisttypename = ?");
212        queryMap.put(EntityPermission.READ_WRITE,
213                "SELECT _ALL_ "
214                + "FROM contactlisttypes, contactlisttypedetails "
215                + "WHERE clsttyp_activedetailid = clsttypdt_contactlisttypedetailid AND clsttypdt_contactlisttypename = ? "
216                + "FOR UPDATE");
217        getContactListTypeByNameQueries = Collections.unmodifiableMap(queryMap);
218    }
219
220    private ContactListType getContactListTypeByName(String contactListTypeName, EntityPermission entityPermission) {
221        return ContactListTypeFactory.getInstance().getEntityFromQuery(entityPermission, getContactListTypeByNameQueries,
222                contactListTypeName);
223    }
224
225    public ContactListType getContactListTypeByName(String contactListTypeName) {
226        return getContactListTypeByName(contactListTypeName, EntityPermission.READ_ONLY);
227    }
228
229    public ContactListType getContactListTypeByNameForUpdate(String contactListTypeName) {
230        return getContactListTypeByName(contactListTypeName, EntityPermission.READ_WRITE);
231    }
232
233    public ContactListTypeDetailValue getContactListTypeDetailValueForUpdate(ContactListType contactListType) {
234        return contactListType == null? null: contactListType.getLastDetailForUpdate().getContactListTypeDetailValue().clone();
235    }
236
237    public ContactListTypeDetailValue getContactListTypeDetailValueByNameForUpdate(String contactListTypeName) {
238        return getContactListTypeDetailValueForUpdate(getContactListTypeByNameForUpdate(contactListTypeName));
239    }
240
241    private static final Map<EntityPermission, String> getDefaultContactListTypeQueries;
242
243    static {
244        Map<EntityPermission, String> queryMap = new HashMap<>(2);
245
246        queryMap.put(EntityPermission.READ_ONLY,
247                "SELECT _ALL_ "
248                + "FROM contactlisttypes, contactlisttypedetails "
249                + "WHERE clsttyp_activedetailid = clsttypdt_contactlisttypedetailid AND clsttypdt_isdefault = 1");
250        queryMap.put(EntityPermission.READ_WRITE,
251                "SELECT _ALL_ "
252                + "FROM contactlisttypes, contactlisttypedetails "
253                + "WHERE clsttyp_activedetailid = clsttypdt_contactlisttypedetailid AND clsttypdt_isdefault = 1 "
254                + "FOR UPDATE");
255        getDefaultContactListTypeQueries = Collections.unmodifiableMap(queryMap);
256    }
257
258    private ContactListType getDefaultContactListType(EntityPermission entityPermission) {
259        return ContactListTypeFactory.getInstance().getEntityFromQuery(entityPermission, getDefaultContactListTypeQueries);
260    }
261
262    public ContactListType getDefaultContactListType() {
263        return getDefaultContactListType(EntityPermission.READ_ONLY);
264    }
265
266    public ContactListType getDefaultContactListTypeForUpdate() {
267        return getDefaultContactListType(EntityPermission.READ_WRITE);
268    }
269
270    public ContactListTypeDetailValue getDefaultContactListTypeDetailValueForUpdate() {
271        return getDefaultContactListType(EntityPermission.READ_WRITE).getLastDetailForUpdate().getContactListTypeDetailValue();
272    }
273
274    private static final Map<EntityPermission, String> getContactListTypesQueries;
275
276    static {
277        Map<EntityPermission, String> queryMap = new HashMap<>(2);
278
279        queryMap.put(EntityPermission.READ_ONLY,
280                "SELECT _ALL_ "
281                + "FROM contactlisttypes, contactlisttypedetails "
282                + "WHERE clsttyp_activedetailid = clsttypdt_contactlisttypedetailid "
283                + "ORDER BY clsttypdt_sortorder, clsttypdt_contactlisttypename");
284        queryMap.put(EntityPermission.READ_WRITE,
285                "SELECT _ALL_ "
286                + "FROM contactlisttypes, contactlisttypedetails "
287                + "WHERE clsttyp_activedetailid = clsttypdt_contactlisttypedetailid "
288                + "FOR UPDATE");
289        getContactListTypesQueries = Collections.unmodifiableMap(queryMap);
290    }
291
292    private List<ContactListType> getContactListTypes(EntityPermission entityPermission) {
293        return ContactListTypeFactory.getInstance().getEntitiesFromQuery(entityPermission, getContactListTypesQueries);
294    }
295
296    public List<ContactListType> getContactListTypes() {
297        return getContactListTypes(EntityPermission.READ_ONLY);
298    }
299
300    public List<ContactListType> getContactListTypesForUpdate() {
301        return getContactListTypes(EntityPermission.READ_WRITE);
302    }
303
304    private static final Map<EntityPermission, String> getContactListTypesByConfirmationRequestChainQueries;
305
306    static {
307        Map<EntityPermission, String> queryMap = new HashMap<>(2);
308
309        queryMap.put(EntityPermission.READ_ONLY,
310                "SELECT _ALL_ "
311                + "FROM contactlisttypes, contactlisttypedetails "
312                + "WHERE clsttyp_activedetailid = clsttypdt_contactlisttypedetailid AND clsttypdt_confirmationrequestchainid = ? "
313                + "ORDER BY clsttypdt_sortorder, clsttypdt_contactlisttypename");
314        queryMap.put(EntityPermission.READ_WRITE,
315                "SELECT _ALL_ "
316                + "FROM contactlisttypes, contactlisttypedetails "
317                + "WHERE clsttyp_activedetailid = clsttypdt_contactlisttypedetailid AND clsttypdt_confirmationrequestchainid = ? "
318                + "FOR UPDATE");
319        getContactListTypesByConfirmationRequestChainQueries = Collections.unmodifiableMap(queryMap);
320    }
321
322    private List<ContactListType> getContactListTypesByConfirmationRequestChain(Chain confirmationRequestChain, EntityPermission entityPermission) {
323        return ContactListTypeFactory.getInstance().getEntitiesFromQuery(entityPermission, getContactListTypesByConfirmationRequestChainQueries,
324                confirmationRequestChain);
325    }
326
327    public List<ContactListType> getContactListTypesByConfirmationRequestChain(Chain confirmationRequestChain) {
328        return getContactListTypesByConfirmationRequestChain(confirmationRequestChain, EntityPermission.READ_ONLY);
329    }
330
331    public List<ContactListType> getContactListTypesByConfirmationRequestChainForUpdate(Chain confirmationRequestChain) {
332        return getContactListTypesByConfirmationRequestChain(confirmationRequestChain, EntityPermission.READ_WRITE);
333    }
334
335    private static final Map<EntityPermission, String> getContactListTypesBySubscribeChainQueries;
336
337    static {
338        Map<EntityPermission, String> queryMap = new HashMap<>(2);
339
340        queryMap.put(EntityPermission.READ_ONLY,
341                "SELECT _ALL_ "
342                + "FROM contactlisttypes, contactlisttypedetails "
343                + "WHERE clsttyp_activedetailid = clsttypdt_contactlisttypedetailid AND clsttypdt_subscribechainid = ? "
344                + "ORDER BY clsttypdt_sortorder, clsttypdt_contactlisttypename");
345        queryMap.put(EntityPermission.READ_WRITE,
346                "SELECT _ALL_ "
347                + "FROM contactlisttypes, contactlisttypedetails "
348                + "WHERE clsttyp_activedetailid = clsttypdt_contactlisttypedetailid AND clsttypdt_subscribechainid = ? "
349                + "FOR UPDATE");
350        getContactListTypesBySubscribeChainQueries = Collections.unmodifiableMap(queryMap);
351    }
352
353    private List<ContactListType> getContactListTypesBySubscribeChain(Chain subscribeChain, EntityPermission entityPermission) {
354        return ContactListTypeFactory.getInstance().getEntitiesFromQuery(entityPermission, getContactListTypesBySubscribeChainQueries,
355                subscribeChain);
356    }
357
358    public List<ContactListType> getContactListTypesBySubscribeChain(Chain subscribeChain) {
359        return getContactListTypesBySubscribeChain(subscribeChain, EntityPermission.READ_ONLY);
360    }
361
362    public List<ContactListType> getContactListTypesBySubscribeChainForUpdate(Chain subscribeChain) {
363        return getContactListTypesBySubscribeChain(subscribeChain, EntityPermission.READ_WRITE);
364    }
365
366    private static final Map<EntityPermission, String> getContactListTypesByUnsubscribeChainQueries;
367
368    static {
369        Map<EntityPermission, String> queryMap = new HashMap<>(2);
370
371        queryMap.put(EntityPermission.READ_ONLY,
372                "SELECT _ALL_ "
373                + "FROM contactlisttypes, contactlisttypedetails "
374                + "WHERE clsttyp_activedetailid = clsttypdt_contactlisttypedetailid AND clsttypdt_unsubscribechainid = ? "
375                + "ORDER BY clsttypdt_sortorder, clsttypdt_contactlisttypename");
376        queryMap.put(EntityPermission.READ_WRITE,
377                "SELECT _ALL_ "
378                + "FROM contactlisttypes, contactlisttypedetails "
379                + "WHERE clsttyp_activedetailid = clsttypdt_contactlisttypedetailid AND clsttypdt_unsubscribechainid = ? "
380                + "FOR UPDATE");
381        getContactListTypesByUnsubscribeChainQueries = Collections.unmodifiableMap(queryMap);
382    }
383
384    private List<ContactListType> getContactListTypesByUnsubscribeChain(Chain unsubscribeChain, EntityPermission entityPermission) {
385        return ContactListTypeFactory.getInstance().getEntitiesFromQuery(entityPermission, getContactListTypesByUnsubscribeChainQueries,
386                unsubscribeChain);
387    }
388
389    public List<ContactListType> getContactListTypesByUnsubscribeChain(Chain unsubscribeChain) {
390        return getContactListTypesByUnsubscribeChain(unsubscribeChain, EntityPermission.READ_ONLY);
391    }
392
393    public List<ContactListType> getContactListTypesByUnsubscribeChainForUpdate(Chain unsubscribeChain) {
394        return getContactListTypesByUnsubscribeChain(unsubscribeChain, EntityPermission.READ_WRITE);
395    }
396
397    public ContactListTypeChoicesBean getContactListTypeChoices(String defaultContactListTypeChoice, Language language, boolean allowNullChoice) {
398        List<ContactListType> contactListTypes = getContactListTypes();
399        var size = contactListTypes.size();
400        var labels = new ArrayList<String>(size);
401        var values = new ArrayList<String>(size);
402        String defaultValue = null;
403
404        if(allowNullChoice) {
405            labels.add("");
406            values.add("");
407
408            if(defaultContactListTypeChoice == null) {
409                defaultValue = "";
410            }
411        }
412
413        for(var contactListType : contactListTypes) {
414            ContactListTypeDetail contactListTypeDetail = contactListType.getLastDetail();
415
416            var label = getBestContactListTypeDescription(contactListType, language);
417            var value = contactListTypeDetail.getContactListTypeName();
418
419            labels.add(label == null? value: label);
420            values.add(value);
421
422            var usingDefaultChoice = defaultContactListTypeChoice != null && defaultContactListTypeChoice.equals(value);
423            if(usingDefaultChoice || (defaultValue == null && contactListTypeDetail.getIsDefault())) {
424                defaultValue = value;
425            }
426        }
427
428        return new ContactListTypeChoicesBean(labels, values, defaultValue);
429    }
430
431    public ContactListTypeTransfer getContactListTypeTransfer(UserVisit userVisit, ContactListType contactListType) {
432        return getContactListTransferCaches(userVisit).getContactListTypeTransferCache().getContactListTypeTransfer(contactListType);
433    }
434
435    public List<ContactListTypeTransfer> getContactListTypeTransfers(UserVisit userVisit) {
436        List<ContactListType> contactListTypes = getContactListTypes();
437        List<ContactListTypeTransfer> contactListTypeTransfers = new ArrayList<>(contactListTypes.size());
438        ContactListTypeTransferCache contactListTypeTransferCache = getContactListTransferCaches(userVisit).getContactListTypeTransferCache();
439
440        contactListTypes.forEach((contactListType) ->
441                contactListTypeTransfers.add(contactListTypeTransferCache.getContactListTypeTransfer(contactListType))
442        );
443
444        return contactListTypeTransfers;
445    }
446
447    private void updateContactListTypeFromValue(ContactListTypeDetailValue contactListTypeDetailValue, boolean checkDefault, BasePK updatedBy) {
448        ContactListType contactListType = ContactListTypeFactory.getInstance().getEntityFromPK(session,
449                EntityPermission.READ_WRITE, contactListTypeDetailValue.getContactListTypePK());
450        ContactListTypeDetail contactListTypeDetail = contactListType.getActiveDetailForUpdate();
451
452        contactListTypeDetail.setThruTime(session.START_TIME_LONG);
453        contactListTypeDetail.store();
454
455        ContactListTypePK contactListTypePK = contactListTypeDetail.getContactListTypePK();
456        String contactListTypeName = contactListTypeDetailValue.getContactListTypeName();
457        ChainPK confirmationRequestChainPK = contactListTypeDetailValue.getConfirmationRequestChainPK();
458        ChainPK subscribeChainPK = contactListTypeDetailValue.getSubscribeChainPK();
459        ChainPK unsubscribeChainPK = contactListTypeDetailValue.getUnsubscribeChainPK();
460        Boolean usedForSolicitation = contactListTypeDetailValue.getUsedForSolicitation();
461        Boolean isDefault = contactListTypeDetailValue.getIsDefault();
462        Integer sortOrder = contactListTypeDetailValue.getSortOrder();
463
464        if(checkDefault) {
465            ContactListType defaultContactListType = getDefaultContactListType();
466            boolean defaultFound = defaultContactListType != null && !defaultContactListType.equals(contactListType);
467
468            if(isDefault && defaultFound) {
469                // If I'm the default, and a default already existed...
470                ContactListTypeDetailValue defaultContactListTypeDetailValue = getDefaultContactListTypeDetailValueForUpdate();
471
472                defaultContactListTypeDetailValue.setIsDefault(Boolean.FALSE);
473                updateContactListTypeFromValue(defaultContactListTypeDetailValue, false, updatedBy);
474            } else if(!isDefault && !defaultFound) {
475                // If I'm not the default, and no other default exists...
476                isDefault = Boolean.TRUE;
477            }
478        }
479
480        contactListTypeDetail = ContactListTypeDetailFactory.getInstance().create(contactListTypePK, contactListTypeName, confirmationRequestChainPK,
481                subscribeChainPK, unsubscribeChainPK, usedForSolicitation, isDefault, sortOrder, session.START_TIME_LONG, Session.MAX_TIME_LONG);
482
483        contactListType.setActiveDetail(contactListTypeDetail);
484        contactListType.setLastDetail(contactListTypeDetail);
485        contactListType.store();
486
487        sendEvent(contactListTypePK, EventTypes.MODIFY, null, null, updatedBy);
488    }
489
490    public void updateContactListTypeFromValue(ContactListTypeDetailValue contactListTypeDetailValue, BasePK updatedBy) {
491        updateContactListTypeFromValue(contactListTypeDetailValue, true, updatedBy);
492    }
493
494    public void deleteContactListType(ContactListType contactListType, BasePK deletedBy) {
495        deleteContactListsByContactListType(contactListType, deletedBy);
496        deleteContactListTypeDescriptionsByContactListType(contactListType, deletedBy);
497
498        ContactListTypeDetail contactListTypeDetail = contactListType.getLastDetailForUpdate();
499        contactListTypeDetail.setThruTime(session.START_TIME_LONG);
500        contactListType.setActiveDetail(null);
501        contactListType.store();
502
503        // Check for default, and pick one if necessary
504        ContactListType defaultContactListType = getDefaultContactListType();
505        if(defaultContactListType == null) {
506            List<ContactListType> contactListTypes = getContactListTypesForUpdate();
507
508            if(!contactListTypes.isEmpty()) {
509                Iterator<ContactListType> iter = contactListTypes.iterator();
510                if(iter.hasNext()) {
511                    defaultContactListType = iter.next();
512                }
513                ContactListTypeDetailValue contactListTypeDetailValue = Objects.requireNonNull(defaultContactListType).getLastDetailForUpdate().getContactListTypeDetailValue().clone();
514
515                contactListTypeDetailValue.setIsDefault(Boolean.TRUE);
516                updateContactListTypeFromValue(contactListTypeDetailValue, false, deletedBy);
517            }
518        }
519
520        sendEvent(contactListType.getPrimaryKey(), EventTypes.DELETE, null, null, deletedBy);
521    }
522
523    public void deleteContactListTypes(List<ContactListType> contactListTypes, BasePK deletedBy) {
524        contactListTypes.forEach((contactListType) -> 
525                deleteContactListType(contactListType, deletedBy)
526        );
527    }
528
529    public void deleteContactListTypesByConfirmationRequestChain(Chain confirmationRequestChain, BasePK deletedBy) {
530        deleteContactListTypes(getContactListTypesByConfirmationRequestChainForUpdate(confirmationRequestChain), deletedBy);
531    }
532
533    public void deleteContactListTypesBySubscribeChain(Chain subscribeChain, BasePK deletedBy) {
534        deleteContactListTypes(getContactListTypesBySubscribeChainForUpdate(subscribeChain), deletedBy);
535    }
536
537    public void deleteContactListTypesByUnsubscribeChain(Chain unsubscribeChain, BasePK deletedBy) {
538        deleteContactListTypes(getContactListTypesByUnsubscribeChainForUpdate(unsubscribeChain), deletedBy);
539    }
540
541    public void deleteContactListTypesByChain(Chain chain, BasePK deletedBy) {
542        deleteContactListTypesByConfirmationRequestChain(chain, deletedBy);
543        deleteContactListTypesBySubscribeChain(chain, deletedBy);
544        deleteContactListTypesByUnsubscribeChain(chain, deletedBy);
545    }
546
547    // --------------------------------------------------------------------------------
548    //   Contact List Type Descriptions
549    // --------------------------------------------------------------------------------
550
551    public ContactListTypeDescription createContactListTypeDescription(ContactListType contactListType, Language language, String description,
552            BasePK createdBy) {
553        ContactListTypeDescription contactListTypeDescription = ContactListTypeDescriptionFactory.getInstance().create(contactListType,
554                language, description, session.START_TIME_LONG, Session.MAX_TIME_LONG);
555
556        sendEvent(contactListType.getPrimaryKey(), EventTypes.MODIFY, contactListTypeDescription.getPrimaryKey(), EventTypes.CREATE, createdBy);
557
558        return contactListTypeDescription;
559    }
560
561    private static final Map<EntityPermission, String> getContactListTypeDescriptionQueries;
562
563    static {
564        Map<EntityPermission, String> queryMap = new HashMap<>(2);
565
566        queryMap.put(EntityPermission.READ_ONLY,
567                "SELECT _ALL_ "
568                + "FROM contactlisttypedescriptions "
569                + "WHERE clsttypd_clsttyp_contactlisttypeid = ? AND clsttypd_lang_languageid = ? AND clsttypd_thrutime = ?");
570        queryMap.put(EntityPermission.READ_WRITE,
571                "SELECT _ALL_ "
572                + "FROM contactlisttypedescriptions "
573                + "WHERE clsttypd_clsttyp_contactlisttypeid = ? AND clsttypd_lang_languageid = ? AND clsttypd_thrutime = ? "
574                + "FOR UPDATE");
575        getContactListTypeDescriptionQueries = Collections.unmodifiableMap(queryMap);
576    }
577
578    private ContactListTypeDescription getContactListTypeDescription(ContactListType contactListType, Language language, EntityPermission entityPermission) {
579        return ContactListTypeDescriptionFactory.getInstance().getEntityFromQuery(entityPermission, getContactListTypeDescriptionQueries,
580                contactListType, language, Session.MAX_TIME);
581    }
582
583    public ContactListTypeDescription getContactListTypeDescription(ContactListType contactListType, Language language) {
584        return getContactListTypeDescription(contactListType, language, EntityPermission.READ_ONLY);
585    }
586
587    public ContactListTypeDescription getContactListTypeDescriptionForUpdate(ContactListType contactListType, Language language) {
588        return getContactListTypeDescription(contactListType, language, EntityPermission.READ_WRITE);
589    }
590
591    public ContactListTypeDescriptionValue getContactListTypeDescriptionValue(ContactListTypeDescription contactListTypeDescription) {
592        return contactListTypeDescription == null? null: contactListTypeDescription.getContactListTypeDescriptionValue().clone();
593    }
594
595    public ContactListTypeDescriptionValue getContactListTypeDescriptionValueForUpdate(ContactListType contactListType, Language language) {
596        return getContactListTypeDescriptionValue(getContactListTypeDescriptionForUpdate(contactListType, language));
597    }
598
599    private static final Map<EntityPermission, String> getContactListTypeDescriptionsByContactListTypeQueries;
600
601    static {
602        Map<EntityPermission, String> queryMap = new HashMap<>(2);
603
604        queryMap.put(EntityPermission.READ_ONLY,
605                "SELECT _ALL_ "
606                + "FROM contactlisttypedescriptions, languages "
607                + "WHERE clsttypd_clsttyp_contactlisttypeid = ? AND clsttypd_thrutime = ? AND clsttypd_lang_languageid = lang_languageid "
608                + "ORDER BY lang_sortorder, lang_languageisoname");
609        queryMap.put(EntityPermission.READ_WRITE,
610                "SELECT _ALL_ "
611                + "FROM contactlisttypedescriptions "
612                + "WHERE clsttypd_clsttyp_contactlisttypeid = ? AND clsttypd_thrutime = ? "
613                + "FOR UPDATE");
614        getContactListTypeDescriptionsByContactListTypeQueries = Collections.unmodifiableMap(queryMap);
615    }
616
617    private List<ContactListTypeDescription> getContactListTypeDescriptionsByContactListType(ContactListType contactListType, EntityPermission entityPermission) {
618        return ContactListTypeDescriptionFactory.getInstance().getEntitiesFromQuery(entityPermission, getContactListTypeDescriptionsByContactListTypeQueries,
619                contactListType, Session.MAX_TIME);
620    }
621
622    public List<ContactListTypeDescription> getContactListTypeDescriptionsByContactListType(ContactListType contactListType) {
623        return getContactListTypeDescriptionsByContactListType(contactListType, EntityPermission.READ_ONLY);
624    }
625
626    public List<ContactListTypeDescription> getContactListTypeDescriptionsByContactListTypeForUpdate(ContactListType contactListType) {
627        return getContactListTypeDescriptionsByContactListType(contactListType, EntityPermission.READ_WRITE);
628    }
629
630    public String getBestContactListTypeDescription(ContactListType contactListType, Language language) {
631        String description;
632        ContactListTypeDescription contactListTypeDescription = getContactListTypeDescription(contactListType, language);
633
634        if(contactListTypeDescription == null && !language.getIsDefault()) {
635            contactListTypeDescription = getContactListTypeDescription(contactListType, getPartyControl().getDefaultLanguage());
636        }
637
638        if(contactListTypeDescription == null) {
639            description = contactListType.getLastDetail().getContactListTypeName();
640        } else {
641            description = contactListTypeDescription.getDescription();
642        }
643
644        return description;
645    }
646
647    public ContactListTypeDescriptionTransfer getContactListTypeDescriptionTransfer(UserVisit userVisit, ContactListTypeDescription contactListTypeDescription) {
648        return getContactListTransferCaches(userVisit).getContactListTypeDescriptionTransferCache().getContactListTypeDescriptionTransfer(contactListTypeDescription);
649    }
650
651    public List<ContactListTypeDescriptionTransfer> getContactListTypeDescriptionTransfersByContactListType(UserVisit userVisit, ContactListType contactListType) {
652        List<ContactListTypeDescription> contactListTypeDescriptions = getContactListTypeDescriptionsByContactListType(contactListType);
653        List<ContactListTypeDescriptionTransfer> contactListTypeDescriptionTransfers = new ArrayList<>(contactListTypeDescriptions.size());
654
655        contactListTypeDescriptions.forEach((contactListTypeDescription) -> {
656            contactListTypeDescriptionTransfers.add(getContactListTransferCaches(userVisit).getContactListTypeDescriptionTransferCache().getContactListTypeDescriptionTransfer(contactListTypeDescription));
657        });
658
659        return contactListTypeDescriptionTransfers;
660    }
661
662    public void updateContactListTypeDescriptionFromValue(ContactListTypeDescriptionValue contactListTypeDescriptionValue, BasePK updatedBy) {
663        if(contactListTypeDescriptionValue.hasBeenModified()) {
664            ContactListTypeDescription contactListTypeDescription = ContactListTypeDescriptionFactory.getInstance().getEntityFromPK(EntityPermission.READ_WRITE,
665                     contactListTypeDescriptionValue.getPrimaryKey());
666
667            contactListTypeDescription.setThruTime(session.START_TIME_LONG);
668            contactListTypeDescription.store();
669
670            ContactListType contactListType = contactListTypeDescription.getContactListType();
671            Language language = contactListTypeDescription.getLanguage();
672            String description = contactListTypeDescriptionValue.getDescription();
673
674            contactListTypeDescription = ContactListTypeDescriptionFactory.getInstance().create(contactListType, language, description,
675                    session.START_TIME_LONG, Session.MAX_TIME_LONG);
676
677            sendEvent(contactListType.getPrimaryKey(), EventTypes.MODIFY, contactListTypeDescription.getPrimaryKey(), EventTypes.MODIFY, updatedBy);
678        }
679    }
680
681    public void deleteContactListTypeDescription(ContactListTypeDescription contactListTypeDescription, BasePK deletedBy) {
682        contactListTypeDescription.setThruTime(session.START_TIME_LONG);
683
684        sendEvent(contactListTypeDescription.getContactListTypePK(), EventTypes.MODIFY, contactListTypeDescription.getPrimaryKey(), EventTypes.DELETE, deletedBy);
685
686    }
687
688    public void deleteContactListTypeDescriptionsByContactListType(ContactListType contactListType, BasePK deletedBy) {
689        List<ContactListTypeDescription> contactListTypeDescriptions = getContactListTypeDescriptionsByContactListTypeForUpdate(contactListType);
690
691        contactListTypeDescriptions.forEach((contactListTypeDescription) -> 
692                deleteContactListTypeDescription(contactListTypeDescription, deletedBy)
693        );
694    }
695
696    // --------------------------------------------------------------------------------
697    //   Contact List Groups
698    // --------------------------------------------------------------------------------
699
700    public ContactListGroup createContactListGroup(String contactListGroupName, Boolean isDefault, Integer sortOrder, BasePK createdBy) {
701        ContactListGroup defaultContactListGroup = getDefaultContactListGroup();
702        boolean defaultFound = defaultContactListGroup != null;
703
704        if(defaultFound && isDefault) {
705            ContactListGroupDetailValue defaultContactListGroupDetailValue = getDefaultContactListGroupDetailValueForUpdate();
706
707            defaultContactListGroupDetailValue.setIsDefault(Boolean.FALSE);
708            updateContactListGroupFromValue(defaultContactListGroupDetailValue, false, createdBy);
709        } else if(!defaultFound) {
710            isDefault = Boolean.TRUE;
711        }
712
713        ContactListGroup contactListGroup = ContactListGroupFactory.getInstance().create();
714        ContactListGroupDetail contactListGroupDetail = ContactListGroupDetailFactory.getInstance().create(contactListGroup, contactListGroupName, isDefault,
715                sortOrder, session.START_TIME_LONG, Session.MAX_TIME_LONG);
716
717        // Convert to R/W
718        contactListGroup = ContactListGroupFactory.getInstance().getEntityFromPK(EntityPermission.READ_WRITE,
719                contactListGroup.getPrimaryKey());
720        contactListGroup.setActiveDetail(contactListGroupDetail);
721        contactListGroup.setLastDetail(contactListGroupDetail);
722        contactListGroup.store();
723
724        sendEvent(contactListGroup.getPrimaryKey(), EventTypes.CREATE, null, null, createdBy);
725
726        return contactListGroup;
727    }
728
729    private static final Map<EntityPermission, String> getContactListGroupByNameQueries;
730
731    static {
732        Map<EntityPermission, String> queryMap = new HashMap<>(2);
733
734        queryMap.put(EntityPermission.READ_ONLY,
735                "SELECT _ALL_ "
736                + "FROM contactlistgroups, contactlistgroupdetails "
737                + "WHERE clstgrp_activedetailid = clstgrpdt_contactlistgroupdetailid AND clstgrpdt_contactlistgroupname = ?");
738        queryMap.put(EntityPermission.READ_WRITE,
739                "SELECT _ALL_ "
740                + "FROM contactlistgroups, contactlistgroupdetails "
741                + "WHERE clstgrp_activedetailid = clstgrpdt_contactlistgroupdetailid AND clstgrpdt_contactlistgroupname = ? "
742                + "FOR UPDATE");
743        getContactListGroupByNameQueries = Collections.unmodifiableMap(queryMap);
744    }
745
746    private ContactListGroup getContactListGroupByName(String contactListGroupName, EntityPermission entityPermission) {
747        return ContactListGroupFactory.getInstance().getEntityFromQuery(entityPermission, getContactListGroupByNameQueries,
748                contactListGroupName);
749    }
750
751    public ContactListGroup getContactListGroupByName(String contactListGroupName) {
752        return getContactListGroupByName(contactListGroupName, EntityPermission.READ_ONLY);
753    }
754
755    public ContactListGroup getContactListGroupByNameForUpdate(String contactListGroupName) {
756        return getContactListGroupByName(contactListGroupName, EntityPermission.READ_WRITE);
757    }
758
759    public ContactListGroupDetailValue getContactListGroupDetailValueForUpdate(ContactListGroup contactListGroup) {
760        return contactListGroup == null? null: contactListGroup.getLastDetailForUpdate().getContactListGroupDetailValue().clone();
761    }
762
763    public ContactListGroupDetailValue getContactListGroupDetailValueByNameForUpdate(String contactListGroupName) {
764        return getContactListGroupDetailValueForUpdate(getContactListGroupByNameForUpdate(contactListGroupName));
765    }
766
767    private static final Map<EntityPermission, String> getDefaultContactListGroupQueries;
768
769    static {
770        Map<EntityPermission, String> queryMap = new HashMap<>(2);
771
772        queryMap.put(EntityPermission.READ_ONLY,
773                "SELECT _ALL_ "
774                + "FROM contactlistgroups, contactlistgroupdetails "
775                + "WHERE clstgrp_activedetailid = clstgrpdt_contactlistgroupdetailid AND clstgrpdt_isdefault = 1");
776        queryMap.put(EntityPermission.READ_WRITE,
777                "SELECT _ALL_ "
778                + "FROM contactlistgroups, contactlistgroupdetails "
779                + "WHERE clstgrp_activedetailid = clstgrpdt_contactlistgroupdetailid AND clstgrpdt_isdefault = 1 "
780                + "FOR UPDATE");
781        getDefaultContactListGroupQueries = Collections.unmodifiableMap(queryMap);
782    }
783
784    private ContactListGroup getDefaultContactListGroup(EntityPermission entityPermission) {
785        return ContactListGroupFactory.getInstance().getEntityFromQuery(entityPermission, getDefaultContactListGroupQueries);
786    }
787
788    public ContactListGroup getDefaultContactListGroup() {
789        return getDefaultContactListGroup(EntityPermission.READ_ONLY);
790    }
791
792    public ContactListGroup getDefaultContactListGroupForUpdate() {
793        return getDefaultContactListGroup(EntityPermission.READ_WRITE);
794    }
795
796    public ContactListGroupDetailValue getDefaultContactListGroupDetailValueForUpdate() {
797        return getDefaultContactListGroup(EntityPermission.READ_WRITE).getLastDetailForUpdate().getContactListGroupDetailValue();
798    }
799
800    private static final Map<EntityPermission, String> getContactListGroupsQueries;
801
802    static {
803        Map<EntityPermission, String> queryMap = new HashMap<>(2);
804
805        queryMap.put(EntityPermission.READ_ONLY,
806                "SELECT _ALL_ "
807                + "FROM contactlistgroups, contactlistgroupdetails "
808                + "WHERE clstgrp_activedetailid = clstgrpdt_contactlistgroupdetailid "
809                + "ORDER BY clstgrpdt_sortorder, clstgrpdt_contactlistgroupname");
810        queryMap.put(EntityPermission.READ_WRITE,
811                "SELECT _ALL_ "
812                + "FROM contactlistgroups, contactlistgroupdetails "
813                + "WHERE clstgrp_activedetailid = clstgrpdt_contactlistgroupdetailid "
814                + "FOR UPDATE");
815        getContactListGroupsQueries = Collections.unmodifiableMap(queryMap);
816    }
817
818    private List<ContactListGroup> getContactListGroups(EntityPermission entityPermission) {
819        return ContactListGroupFactory.getInstance().getEntitiesFromQuery(entityPermission, getContactListGroupsQueries);
820    }
821
822    public List<ContactListGroup> getContactListGroups() {
823        return getContactListGroups(EntityPermission.READ_ONLY);
824    }
825
826    public List<ContactListGroup> getContactListGroupsForUpdate() {
827        return getContactListGroups(EntityPermission.READ_WRITE);
828    }
829
830    public ContactListGroupChoicesBean getContactListGroupChoices(String defaultContactListGroupChoice, Language language, boolean allowNullChoice) {
831        List<ContactListGroup> contactListGroups = getContactListGroups();
832        var size = contactListGroups.size();
833        var labels = new ArrayList<String>(size);
834        var values = new ArrayList<String>(size);
835        String defaultValue = null;
836
837        if(allowNullChoice) {
838            labels.add("");
839            values.add("");
840
841            if(defaultContactListGroupChoice == null) {
842                defaultValue = "";
843            }
844        }
845
846        for(var contactListGroup : contactListGroups) {
847            ContactListGroupDetail contactListGroupDetail = contactListGroup.getLastDetail();
848
849            var label = getBestContactListGroupDescription(contactListGroup, language);
850            var value = contactListGroupDetail.getContactListGroupName();
851
852            labels.add(label == null? value: label);
853            values.add(value);
854
855            var usingDefaultChoice = defaultContactListGroupChoice != null && defaultContactListGroupChoice.equals(value);
856            if(usingDefaultChoice || (defaultValue == null && contactListGroupDetail.getIsDefault())) {
857                defaultValue = value;
858            }
859        }
860
861        return new ContactListGroupChoicesBean(labels, values, defaultValue);
862    }
863
864    public ContactListGroupTransfer getContactListGroupTransfer(UserVisit userVisit, ContactListGroup contactListGroup) {
865        return getContactListTransferCaches(userVisit).getContactListGroupTransferCache().getContactListGroupTransfer(contactListGroup);
866    }
867
868    public List<ContactListGroupTransfer> getContactListGroupTransfers(UserVisit userVisit) {
869        List<ContactListGroup> contactListGroups = getContactListGroups();
870        List<ContactListGroupTransfer> contactListGroupTransfers = new ArrayList<>(contactListGroups.size());
871        ContactListGroupTransferCache contactListGroupTransferCache = getContactListTransferCaches(userVisit).getContactListGroupTransferCache();
872
873        contactListGroups.forEach((contactListGroup) ->
874                contactListGroupTransfers.add(contactListGroupTransferCache.getContactListGroupTransfer(contactListGroup))
875        );
876
877        return contactListGroupTransfers;
878    }
879
880    private void updateContactListGroupFromValue(ContactListGroupDetailValue contactListGroupDetailValue, boolean checkDefault, BasePK updatedBy) {
881        ContactListGroup contactListGroup = ContactListGroupFactory.getInstance().getEntityFromPK(session,
882                EntityPermission.READ_WRITE, contactListGroupDetailValue.getContactListGroupPK());
883        ContactListGroupDetail contactListGroupDetail = contactListGroup.getActiveDetailForUpdate();
884
885        contactListGroupDetail.setThruTime(session.START_TIME_LONG);
886        contactListGroupDetail.store();
887
888        ContactListGroupPK contactListGroupPK = contactListGroupDetail.getContactListGroupPK();
889        String contactListGroupName = contactListGroupDetailValue.getContactListGroupName();
890        Boolean isDefault = contactListGroupDetailValue.getIsDefault();
891        Integer sortOrder = contactListGroupDetailValue.getSortOrder();
892
893        if(checkDefault) {
894            ContactListGroup defaultContactListGroup = getDefaultContactListGroup();
895            boolean defaultFound = defaultContactListGroup != null && !defaultContactListGroup.equals(contactListGroup);
896
897            if(isDefault && defaultFound) {
898                // If I'm the default, and a default already existed...
899                ContactListGroupDetailValue defaultContactListGroupDetailValue = getDefaultContactListGroupDetailValueForUpdate();
900
901                defaultContactListGroupDetailValue.setIsDefault(Boolean.FALSE);
902                updateContactListGroupFromValue(defaultContactListGroupDetailValue, false, updatedBy);
903            } else if(!isDefault && !defaultFound) {
904                // If I'm not the default, and no other default exists...
905                isDefault = Boolean.TRUE;
906            }
907        }
908
909        contactListGroupDetail = ContactListGroupDetailFactory.getInstance().create(contactListGroupPK, contactListGroupName, isDefault, sortOrder,
910                session.START_TIME_LONG, Session.MAX_TIME_LONG);
911
912        contactListGroup.setActiveDetail(contactListGroupDetail);
913        contactListGroup.setLastDetail(contactListGroupDetail);
914        contactListGroup.store();
915
916        sendEvent(contactListGroupPK, EventTypes.MODIFY, null, null, updatedBy);
917    }
918
919    public void updateContactListGroupFromValue(ContactListGroupDetailValue contactListGroupDetailValue, BasePK updatedBy) {
920        updateContactListGroupFromValue(contactListGroupDetailValue, true, updatedBy);
921    }
922
923    public void deleteContactListGroup(ContactListGroup contactListGroup, BasePK deletedBy) {
924        deleteContactListsByContactListGroup(contactListGroup, deletedBy);
925        deletePartyTypeContactListGroupsByContactListGroup(contactListGroup, deletedBy);
926        deleteCustomerTypeContactListGroupsByContactListGroup(contactListGroup, deletedBy);
927        deleteCustomerTypeContactListGroupsByContactListGroup(contactListGroup, deletedBy);
928        deleteContactListGroupDescriptionsByContactListGroup(contactListGroup, deletedBy);
929
930        ContactListGroupDetail contactListGroupDetail = contactListGroup.getLastDetailForUpdate();
931        contactListGroupDetail.setThruTime(session.START_TIME_LONG);
932        contactListGroup.setActiveDetail(null);
933        contactListGroup.store();
934
935        // Check for default, and pick one if necessary
936        ContactListGroup defaultContactListGroup = getDefaultContactListGroup();
937        if(defaultContactListGroup == null) {
938            List<ContactListGroup> contactListGroups = getContactListGroupsForUpdate();
939
940            if(!contactListGroups.isEmpty()) {
941                Iterator<ContactListGroup> iter = contactListGroups.iterator();
942                if(iter.hasNext()) {
943                    defaultContactListGroup = iter.next();
944                }
945                ContactListGroupDetailValue contactListGroupDetailValue = Objects.requireNonNull(defaultContactListGroup).getLastDetailForUpdate().getContactListGroupDetailValue().clone();
946
947                contactListGroupDetailValue.setIsDefault(Boolean.TRUE);
948                updateContactListGroupFromValue(contactListGroupDetailValue, false, deletedBy);
949            }
950        }
951
952        sendEvent(contactListGroup.getPrimaryKey(), EventTypes.DELETE, null, null, deletedBy);
953    }
954
955    // --------------------------------------------------------------------------------
956    //   Contact List Group Descriptions
957    // --------------------------------------------------------------------------------
958
959    public ContactListGroupDescription createContactListGroupDescription(ContactListGroup contactListGroup, Language language, String description,
960            BasePK createdBy) {
961        ContactListGroupDescription contactListGroupDescription = ContactListGroupDescriptionFactory.getInstance().create(contactListGroup,
962                language, description, session.START_TIME_LONG, Session.MAX_TIME_LONG);
963
964        sendEvent(contactListGroup.getPrimaryKey(), EventTypes.MODIFY, contactListGroupDescription.getPrimaryKey(), EventTypes.CREATE, createdBy);
965
966        return contactListGroupDescription;
967    }
968
969    private static final Map<EntityPermission, String> getContactListGroupDescriptionQueries;
970
971    static {
972        Map<EntityPermission, String> queryMap = new HashMap<>(2);
973
974        queryMap.put(EntityPermission.READ_ONLY,
975                "SELECT _ALL_ "
976                + "FROM contactlistgroupdescriptions "
977                + "WHERE clstgrpd_clstgrp_contactlistgroupid = ? AND clstgrpd_lang_languageid = ? AND clstgrpd_thrutime = ?");
978        queryMap.put(EntityPermission.READ_WRITE,
979                "SELECT _ALL_ "
980                + "FROM contactlistgroupdescriptions "
981                + "WHERE clstgrpd_clstgrp_contactlistgroupid = ? AND clstgrpd_lang_languageid = ? AND clstgrpd_thrutime = ? "
982                + "FOR UPDATE");
983        getContactListGroupDescriptionQueries = Collections.unmodifiableMap(queryMap);
984    }
985
986    private ContactListGroupDescription getContactListGroupDescription(ContactListGroup contactListGroup, Language language, EntityPermission entityPermission) {
987        return ContactListGroupDescriptionFactory.getInstance().getEntityFromQuery(entityPermission, getContactListGroupDescriptionQueries,
988                contactListGroup, language, Session.MAX_TIME);
989    }
990
991    public ContactListGroupDescription getContactListGroupDescription(ContactListGroup contactListGroup, Language language) {
992        return getContactListGroupDescription(contactListGroup, language, EntityPermission.READ_ONLY);
993    }
994
995    public ContactListGroupDescription getContactListGroupDescriptionForUpdate(ContactListGroup contactListGroup, Language language) {
996        return getContactListGroupDescription(contactListGroup, language, EntityPermission.READ_WRITE);
997    }
998
999    public ContactListGroupDescriptionValue getContactListGroupDescriptionValue(ContactListGroupDescription contactListGroupDescription) {
1000        return contactListGroupDescription == null? null: contactListGroupDescription.getContactListGroupDescriptionValue().clone();
1001    }
1002
1003    public ContactListGroupDescriptionValue getContactListGroupDescriptionValueForUpdate(ContactListGroup contactListGroup, Language language) {
1004        return getContactListGroupDescriptionValue(getContactListGroupDescriptionForUpdate(contactListGroup, language));
1005    }
1006
1007    private static final Map<EntityPermission, String> getContactListGroupDescriptionsByContactListGroupQueries;
1008
1009    static {
1010        Map<EntityPermission, String> queryMap = new HashMap<>(2);
1011
1012        queryMap.put(EntityPermission.READ_ONLY,
1013                "SELECT _ALL_ "
1014                + "FROM contactlistgroupdescriptions, languages "
1015                + "WHERE clstgrpd_clstgrp_contactlistgroupid = ? AND clstgrpd_thrutime = ? AND clstgrpd_lang_languageid = lang_languageid "
1016                + "ORDER BY lang_sortorder, lang_languageisoname");
1017        queryMap.put(EntityPermission.READ_WRITE,
1018                "SELECT _ALL_ "
1019                + "FROM contactlistgroupdescriptions "
1020                + "WHERE clstgrpd_clstgrp_contactlistgroupid = ? AND clstgrpd_thrutime = ? "
1021                + "FOR UPDATE");
1022        getContactListGroupDescriptionsByContactListGroupQueries = Collections.unmodifiableMap(queryMap);
1023    }
1024
1025    private List<ContactListGroupDescription> getContactListGroupDescriptionsByContactListGroup(ContactListGroup contactListGroup, EntityPermission entityPermission) {
1026        return ContactListGroupDescriptionFactory.getInstance().getEntitiesFromQuery(entityPermission, getContactListGroupDescriptionsByContactListGroupQueries,
1027                contactListGroup, Session.MAX_TIME);
1028    }
1029
1030    public List<ContactListGroupDescription> getContactListGroupDescriptionsByContactListGroup(ContactListGroup contactListGroup) {
1031        return getContactListGroupDescriptionsByContactListGroup(contactListGroup, EntityPermission.READ_ONLY);
1032    }
1033
1034    public List<ContactListGroupDescription> getContactListGroupDescriptionsByContactListGroupForUpdate(ContactListGroup contactListGroup) {
1035        return getContactListGroupDescriptionsByContactListGroup(contactListGroup, EntityPermission.READ_WRITE);
1036    }
1037
1038    public String getBestContactListGroupDescription(ContactListGroup contactListGroup, Language language) {
1039        String description;
1040        ContactListGroupDescription contactListGroupDescription = getContactListGroupDescription(contactListGroup, language);
1041
1042        if(contactListGroupDescription == null && !language.getIsDefault()) {
1043            contactListGroupDescription = getContactListGroupDescription(contactListGroup, getPartyControl().getDefaultLanguage());
1044        }
1045
1046        if(contactListGroupDescription == null) {
1047            description = contactListGroup.getLastDetail().getContactListGroupName();
1048        } else {
1049            description = contactListGroupDescription.getDescription();
1050        }
1051
1052        return description;
1053    }
1054
1055    public ContactListGroupDescriptionTransfer getContactListGroupDescriptionTransfer(UserVisit userVisit, ContactListGroupDescription contactListGroupDescription) {
1056        return getContactListTransferCaches(userVisit).getContactListGroupDescriptionTransferCache().getContactListGroupDescriptionTransfer(contactListGroupDescription);
1057    }
1058
1059    public List<ContactListGroupDescriptionTransfer> getContactListGroupDescriptionTransfersByContactListGroup(UserVisit userVisit, ContactListGroup contactListGroup) {
1060        List<ContactListGroupDescription> contactListGroupDescriptions = getContactListGroupDescriptionsByContactListGroup(contactListGroup);
1061        List<ContactListGroupDescriptionTransfer> contactListGroupDescriptionTransfers = new ArrayList<>(contactListGroupDescriptions.size());
1062
1063        contactListGroupDescriptions.forEach((contactListGroupDescription) -> {
1064            contactListGroupDescriptionTransfers.add(getContactListTransferCaches(userVisit).getContactListGroupDescriptionTransferCache().getContactListGroupDescriptionTransfer(contactListGroupDescription));
1065        });
1066
1067        return contactListGroupDescriptionTransfers;
1068    }
1069
1070    public void updateContactListGroupDescriptionFromValue(ContactListGroupDescriptionValue contactListGroupDescriptionValue, BasePK updatedBy) {
1071        if(contactListGroupDescriptionValue.hasBeenModified()) {
1072            ContactListGroupDescription contactListGroupDescription = ContactListGroupDescriptionFactory.getInstance().getEntityFromPK(EntityPermission.READ_WRITE,
1073                     contactListGroupDescriptionValue.getPrimaryKey());
1074
1075            contactListGroupDescription.setThruTime(session.START_TIME_LONG);
1076            contactListGroupDescription.store();
1077
1078            ContactListGroup contactListGroup = contactListGroupDescription.getContactListGroup();
1079            Language language = contactListGroupDescription.getLanguage();
1080            String description = contactListGroupDescriptionValue.getDescription();
1081
1082            contactListGroupDescription = ContactListGroupDescriptionFactory.getInstance().create(contactListGroup, language, description,
1083                    session.START_TIME_LONG, Session.MAX_TIME_LONG);
1084
1085            sendEvent(contactListGroup.getPrimaryKey(), EventTypes.MODIFY, contactListGroupDescription.getPrimaryKey(), EventTypes.MODIFY, updatedBy);
1086        }
1087    }
1088
1089    public void deleteContactListGroupDescription(ContactListGroupDescription contactListGroupDescription, BasePK deletedBy) {
1090        contactListGroupDescription.setThruTime(session.START_TIME_LONG);
1091
1092        sendEvent(contactListGroupDescription.getContactListGroupPK(), EventTypes.MODIFY, contactListGroupDescription.getPrimaryKey(), EventTypes.DELETE, deletedBy);
1093
1094    }
1095
1096    public void deleteContactListGroupDescriptionsByContactListGroup(ContactListGroup contactListGroup, BasePK deletedBy) {
1097        List<ContactListGroupDescription> contactListGroupDescriptions = getContactListGroupDescriptionsByContactListGroupForUpdate(contactListGroup);
1098
1099        contactListGroupDescriptions.forEach((contactListGroupDescription) -> 
1100                deleteContactListGroupDescription(contactListGroupDescription, deletedBy)
1101        );
1102    }
1103
1104    // --------------------------------------------------------------------------------
1105    //   Contact List Frequencies
1106    // --------------------------------------------------------------------------------
1107
1108    public ContactListFrequency createContactListFrequency(String contactListFrequencyName, Boolean isDefault, Integer sortOrder, BasePK createdBy) {
1109        ContactListFrequency defaultContactListFrequency = getDefaultContactListFrequency();
1110        boolean defaultFound = defaultContactListFrequency != null;
1111
1112        if(defaultFound && isDefault) {
1113            ContactListFrequencyDetailValue defaultContactListFrequencyDetailValue = getDefaultContactListFrequencyDetailValueForUpdate();
1114
1115            defaultContactListFrequencyDetailValue.setIsDefault(Boolean.FALSE);
1116            updateContactListFrequencyFromValue(defaultContactListFrequencyDetailValue, false, createdBy);
1117        } else if(!defaultFound) {
1118            isDefault = Boolean.TRUE;
1119        }
1120
1121        ContactListFrequency contactListFrequency = ContactListFrequencyFactory.getInstance().create();
1122        ContactListFrequencyDetail contactListFrequencyDetail = ContactListFrequencyDetailFactory.getInstance().create(contactListFrequency, contactListFrequencyName, isDefault,
1123                sortOrder, session.START_TIME_LONG, Session.MAX_TIME_LONG);
1124
1125        // Convert to R/W
1126        contactListFrequency = ContactListFrequencyFactory.getInstance().getEntityFromPK(EntityPermission.READ_WRITE,
1127                contactListFrequency.getPrimaryKey());
1128        contactListFrequency.setActiveDetail(contactListFrequencyDetail);
1129        contactListFrequency.setLastDetail(contactListFrequencyDetail);
1130        contactListFrequency.store();
1131
1132        sendEvent(contactListFrequency.getPrimaryKey(), EventTypes.CREATE, null, null, createdBy);
1133
1134        return contactListFrequency;
1135    }
1136
1137    private static final Map<EntityPermission, String> getContactListFrequencyByNameQueries;
1138
1139    static {
1140        Map<EntityPermission, String> queryMap = new HashMap<>(2);
1141
1142        queryMap.put(EntityPermission.READ_ONLY,
1143                "SELECT _ALL_ "
1144                + "FROM contactlistfrequencies, contactlistfrequencydetails "
1145                + "WHERE clstfrq_activedetailid = clstfrqdt_contactlistfrequencydetailid AND clstfrqdt_contactlistfrequencyname = ?");
1146        queryMap.put(EntityPermission.READ_WRITE,
1147                "SELECT _ALL_ "
1148                + "FROM contactlistfrequencies, contactlistfrequencydetails "
1149                + "WHERE clstfrq_activedetailid = clstfrqdt_contactlistfrequencydetailid AND clstfrqdt_contactlistfrequencyname = ? "
1150                + "FOR UPDATE");
1151        getContactListFrequencyByNameQueries = Collections.unmodifiableMap(queryMap);
1152    }
1153
1154    private ContactListFrequency getContactListFrequencyByName(String contactListFrequencyName, EntityPermission entityPermission) {
1155        return ContactListFrequencyFactory.getInstance().getEntityFromQuery(entityPermission, getContactListFrequencyByNameQueries,
1156                contactListFrequencyName);
1157    }
1158
1159    public ContactListFrequency getContactListFrequencyByName(String contactListFrequencyName) {
1160        return getContactListFrequencyByName(contactListFrequencyName, EntityPermission.READ_ONLY);
1161    }
1162
1163    public ContactListFrequency getContactListFrequencyByNameForUpdate(String contactListFrequencyName) {
1164        return getContactListFrequencyByName(contactListFrequencyName, EntityPermission.READ_WRITE);
1165    }
1166
1167    public ContactListFrequencyDetailValue getContactListFrequencyDetailValueForUpdate(ContactListFrequency contactListFrequency) {
1168        return contactListFrequency == null? null: contactListFrequency.getLastDetailForUpdate().getContactListFrequencyDetailValue().clone();
1169    }
1170
1171    public ContactListFrequencyDetailValue getContactListFrequencyDetailValueByNameForUpdate(String contactListFrequencyName) {
1172        return getContactListFrequencyDetailValueForUpdate(getContactListFrequencyByNameForUpdate(contactListFrequencyName));
1173    }
1174
1175    private static final Map<EntityPermission, String> getDefaultContactListFrequencyQueries;
1176
1177    static {
1178        Map<EntityPermission, String> queryMap = new HashMap<>(2);
1179
1180        queryMap.put(EntityPermission.READ_ONLY,
1181                "SELECT _ALL_ "
1182                + "FROM contactlistfrequencies, contactlistfrequencydetails "
1183                + "WHERE clstfrq_activedetailid = clstfrqdt_contactlistfrequencydetailid AND clstfrqdt_isdefault = 1");
1184        queryMap.put(EntityPermission.READ_WRITE,
1185                "SELECT _ALL_ "
1186                + "FROM contactlistfrequencies, contactlistfrequencydetails "
1187                + "WHERE clstfrq_activedetailid = clstfrqdt_contactlistfrequencydetailid AND clstfrqdt_isdefault = 1 "
1188                + "FOR UPDATE");
1189        getDefaultContactListFrequencyQueries = Collections.unmodifiableMap(queryMap);
1190    }
1191
1192    private ContactListFrequency getDefaultContactListFrequency(EntityPermission entityPermission) {
1193        return ContactListFrequencyFactory.getInstance().getEntityFromQuery(entityPermission, getDefaultContactListFrequencyQueries);
1194    }
1195
1196    public ContactListFrequency getDefaultContactListFrequency() {
1197        return getDefaultContactListFrequency(EntityPermission.READ_ONLY);
1198    }
1199
1200    public ContactListFrequency getDefaultContactListFrequencyForUpdate() {
1201        return getDefaultContactListFrequency(EntityPermission.READ_WRITE);
1202    }
1203
1204    public ContactListFrequencyDetailValue getDefaultContactListFrequencyDetailValueForUpdate() {
1205        return getDefaultContactListFrequency(EntityPermission.READ_WRITE).getLastDetailForUpdate().getContactListFrequencyDetailValue();
1206    }
1207
1208    private static final Map<EntityPermission, String> getContactListFrequenciesQueries;
1209
1210    static {
1211        Map<EntityPermission, String> queryMap = new HashMap<>(2);
1212
1213        queryMap.put(EntityPermission.READ_ONLY,
1214                "SELECT _ALL_ "
1215                + "FROM contactlistfrequencies, contactlistfrequencydetails "
1216                + "WHERE clstfrq_activedetailid = clstfrqdt_contactlistfrequencydetailid "
1217                + "ORDER BY clstfrqdt_sortorder, clstfrqdt_contactlistfrequencyname");
1218        queryMap.put(EntityPermission.READ_WRITE,
1219                "SELECT _ALL_ "
1220                + "FROM contactlistfrequencies, contactlistfrequencydetails "
1221                + "WHERE clstfrq_activedetailid = clstfrqdt_contactlistfrequencydetailid "
1222                + "FOR UPDATE");
1223        getContactListFrequenciesQueries = Collections.unmodifiableMap(queryMap);
1224    }
1225
1226    private List<ContactListFrequency> getContactListFrequencies(EntityPermission entityPermission) {
1227        return ContactListFrequencyFactory.getInstance().getEntitiesFromQuery(entityPermission, getContactListFrequenciesQueries);
1228    }
1229
1230    public List<ContactListFrequency> getContactListFrequencies() {
1231        return getContactListFrequencies(EntityPermission.READ_ONLY);
1232    }
1233
1234    public List<ContactListFrequency> getContactListFrequenciesForUpdate() {
1235        return getContactListFrequencies(EntityPermission.READ_WRITE);
1236    }
1237
1238    public ContactListFrequencyChoicesBean getContactListFrequencyChoices(String defaultContactListFrequencyChoice, Language language, boolean allowNullChoice) {
1239        List<ContactListFrequency> contactListFrequencies = getContactListFrequencies();
1240        var size = contactListFrequencies.size();
1241        var labels = new ArrayList<String>(size);
1242        var values = new ArrayList<String>(size);
1243        String defaultValue = null;
1244
1245        if(allowNullChoice) {
1246            labels.add("");
1247            values.add("");
1248
1249            if(defaultContactListFrequencyChoice == null) {
1250                defaultValue = "";
1251            }
1252        }
1253
1254        for(var contactListFrequency : contactListFrequencies) {
1255            ContactListFrequencyDetail contactListFrequencyDetail = contactListFrequency.getLastDetail();
1256
1257            var label = getBestContactListFrequencyDescription(contactListFrequency, language);
1258            var value = contactListFrequencyDetail.getContactListFrequencyName();
1259
1260            labels.add(label == null? value: label);
1261            values.add(value);
1262
1263            var usingDefaultChoice = defaultContactListFrequencyChoice != null && defaultContactListFrequencyChoice.equals(value);
1264            if(usingDefaultChoice || (defaultValue == null && contactListFrequencyDetail.getIsDefault())) {
1265                defaultValue = value;
1266            }
1267        }
1268
1269        return new ContactListFrequencyChoicesBean(labels, values, defaultValue);
1270    }
1271
1272    public ContactListFrequencyTransfer getContactListFrequencyTransfer(UserVisit userVisit, ContactListFrequency contactListFrequency) {
1273        return getContactListTransferCaches(userVisit).getContactListFrequencyTransferCache().getContactListFrequencyTransfer(contactListFrequency);
1274    }
1275
1276    public List<ContactListFrequencyTransfer> getContactListFrequencyTransfers(UserVisit userVisit) {
1277        List<ContactListFrequency> contactListFrequencies = getContactListFrequencies();
1278        List<ContactListFrequencyTransfer> contactListFrequencyTransfers = new ArrayList<>(contactListFrequencies.size());
1279        ContactListFrequencyTransferCache contactListFrequencyTransferCache = getContactListTransferCaches(userVisit).getContactListFrequencyTransferCache();
1280
1281        contactListFrequencies.forEach((contactListFrequency) ->
1282                contactListFrequencyTransfers.add(contactListFrequencyTransferCache.getContactListFrequencyTransfer(contactListFrequency))
1283        );
1284
1285        return contactListFrequencyTransfers;
1286    }
1287
1288    private void updateContactListFrequencyFromValue(ContactListFrequencyDetailValue contactListFrequencyDetailValue, boolean checkDefault, BasePK updatedBy) {
1289        ContactListFrequency contactListFrequency = ContactListFrequencyFactory.getInstance().getEntityFromPK(session,
1290                EntityPermission.READ_WRITE, contactListFrequencyDetailValue.getContactListFrequencyPK());
1291        ContactListFrequencyDetail contactListFrequencyDetail = contactListFrequency.getActiveDetailForUpdate();
1292
1293        contactListFrequencyDetail.setThruTime(session.START_TIME_LONG);
1294        contactListFrequencyDetail.store();
1295
1296        ContactListFrequencyPK contactListFrequencyPK = contactListFrequencyDetail.getContactListFrequencyPK();
1297        String contactListFrequencyName = contactListFrequencyDetailValue.getContactListFrequencyName();
1298        Boolean isDefault = contactListFrequencyDetailValue.getIsDefault();
1299        Integer sortOrder = contactListFrequencyDetailValue.getSortOrder();
1300
1301        if(checkDefault) {
1302            ContactListFrequency defaultContactListFrequency = getDefaultContactListFrequency();
1303            boolean defaultFound = defaultContactListFrequency != null && !defaultContactListFrequency.equals(contactListFrequency);
1304
1305            if(isDefault && defaultFound) {
1306                // If I'm the default, and a default already existed...
1307                ContactListFrequencyDetailValue defaultContactListFrequencyDetailValue = getDefaultContactListFrequencyDetailValueForUpdate();
1308
1309                defaultContactListFrequencyDetailValue.setIsDefault(Boolean.FALSE);
1310                updateContactListFrequencyFromValue(defaultContactListFrequencyDetailValue, false, updatedBy);
1311            } else if(!isDefault && !defaultFound) {
1312                // If I'm not the default, and no other default exists...
1313                isDefault = Boolean.TRUE;
1314            }
1315        }
1316
1317        contactListFrequencyDetail = ContactListFrequencyDetailFactory.getInstance().create(contactListFrequencyPK, contactListFrequencyName, isDefault, sortOrder,
1318                session.START_TIME_LONG, Session.MAX_TIME_LONG);
1319
1320        contactListFrequency.setActiveDetail(contactListFrequencyDetail);
1321        contactListFrequency.setLastDetail(contactListFrequencyDetail);
1322        contactListFrequency.store();
1323
1324        sendEvent(contactListFrequencyPK, EventTypes.MODIFY, null, null, updatedBy);
1325    }
1326
1327    public void updateContactListFrequencyFromValue(ContactListFrequencyDetailValue contactListFrequencyDetailValue, BasePK updatedBy) {
1328        updateContactListFrequencyFromValue(contactListFrequencyDetailValue, true, updatedBy);
1329    }
1330
1331    public void deleteContactListFrequency(ContactListFrequency contactListFrequency, BasePK deletedBy) {
1332        deleteContactListsByContactListFrequency(contactListFrequency, deletedBy);
1333        deleteContactListFrequencyDescriptionsByContactListFrequency(contactListFrequency, deletedBy);
1334
1335        ContactListFrequencyDetail contactListFrequencyDetail = contactListFrequency.getLastDetailForUpdate();
1336        contactListFrequencyDetail.setThruTime(session.START_TIME_LONG);
1337        contactListFrequency.setActiveDetail(null);
1338        contactListFrequency.store();
1339
1340        // Check for default, and pick one if necessary
1341        ContactListFrequency defaultContactListFrequency = getDefaultContactListFrequency();
1342        if(defaultContactListFrequency == null) {
1343            List<ContactListFrequency> contactListFrequencies = getContactListFrequenciesForUpdate();
1344
1345            if(!contactListFrequencies.isEmpty()) {
1346                Iterator<ContactListFrequency> iter = contactListFrequencies.iterator();
1347                if(iter.hasNext()) {
1348                    defaultContactListFrequency = iter.next();
1349                }
1350                ContactListFrequencyDetailValue contactListFrequencyDetailValue = Objects.requireNonNull(defaultContactListFrequency).getLastDetailForUpdate().getContactListFrequencyDetailValue().clone();
1351
1352                contactListFrequencyDetailValue.setIsDefault(Boolean.TRUE);
1353                updateContactListFrequencyFromValue(contactListFrequencyDetailValue, false, deletedBy);
1354            }
1355        }
1356
1357        sendEvent(contactListFrequency.getPrimaryKey(), EventTypes.DELETE, null, null, deletedBy);
1358    }
1359
1360    // --------------------------------------------------------------------------------
1361    //   Contact List Frequency Descriptions
1362    // --------------------------------------------------------------------------------
1363
1364    public ContactListFrequencyDescription createContactListFrequencyDescription(ContactListFrequency contactListFrequency, Language language, String description,
1365            BasePK createdBy) {
1366        ContactListFrequencyDescription contactListFrequencyDescription = ContactListFrequencyDescriptionFactory.getInstance().create(contactListFrequency,
1367                language, description, session.START_TIME_LONG, Session.MAX_TIME_LONG);
1368
1369        sendEvent(contactListFrequency.getPrimaryKey(), EventTypes.MODIFY, contactListFrequencyDescription.getPrimaryKey(), EventTypes.CREATE, createdBy);
1370
1371        return contactListFrequencyDescription;
1372    }
1373
1374    private static final Map<EntityPermission, String> getContactListFrequencyDescriptionQueries;
1375
1376    static {
1377        Map<EntityPermission, String> queryMap = new HashMap<>(2);
1378
1379        queryMap.put(EntityPermission.READ_ONLY,
1380                "SELECT _ALL_ "
1381                + "FROM contactlistfrequencydescriptions "
1382                + "WHERE clstfrqd_clstfrq_contactlistfrequencyid = ? AND clstfrqd_lang_languageid = ? AND clstfrqd_thrutime = ?");
1383        queryMap.put(EntityPermission.READ_WRITE,
1384                "SELECT _ALL_ "
1385                + "FROM contactlistfrequencydescriptions "
1386                + "WHERE clstfrqd_clstfrq_contactlistfrequencyid = ? AND clstfrqd_lang_languageid = ? AND clstfrqd_thrutime = ? "
1387                + "FOR UPDATE");
1388        getContactListFrequencyDescriptionQueries = Collections.unmodifiableMap(queryMap);
1389    }
1390
1391    private ContactListFrequencyDescription getContactListFrequencyDescription(ContactListFrequency contactListFrequency, Language language, EntityPermission entityPermission) {
1392        return ContactListFrequencyDescriptionFactory.getInstance().getEntityFromQuery(entityPermission, getContactListFrequencyDescriptionQueries,
1393                contactListFrequency, language, Session.MAX_TIME);
1394    }
1395
1396    public ContactListFrequencyDescription getContactListFrequencyDescription(ContactListFrequency contactListFrequency, Language language) {
1397        return getContactListFrequencyDescription(contactListFrequency, language, EntityPermission.READ_ONLY);
1398    }
1399
1400    public ContactListFrequencyDescription getContactListFrequencyDescriptionForUpdate(ContactListFrequency contactListFrequency, Language language) {
1401        return getContactListFrequencyDescription(contactListFrequency, language, EntityPermission.READ_WRITE);
1402    }
1403
1404    public ContactListFrequencyDescriptionValue getContactListFrequencyDescriptionValue(ContactListFrequencyDescription contactListFrequencyDescription) {
1405        return contactListFrequencyDescription == null? null: contactListFrequencyDescription.getContactListFrequencyDescriptionValue().clone();
1406    }
1407
1408    public ContactListFrequencyDescriptionValue getContactListFrequencyDescriptionValueForUpdate(ContactListFrequency contactListFrequency, Language language) {
1409        return getContactListFrequencyDescriptionValue(getContactListFrequencyDescriptionForUpdate(contactListFrequency, language));
1410    }
1411
1412    private static final Map<EntityPermission, String> getContactListFrequencyDescriptionsByContactListFrequencyQueries;
1413
1414    static {
1415        Map<EntityPermission, String> queryMap = new HashMap<>(2);
1416
1417        queryMap.put(EntityPermission.READ_ONLY,
1418                "SELECT _ALL_ "
1419                + "FROM contactlistfrequencydescriptions, languages "
1420                + "WHERE clstfrqd_clstfrq_contactlistfrequencyid = ? AND clstfrqd_thrutime = ? AND clstfrqd_lang_languageid = lang_languageid "
1421                + "ORDER BY lang_sortorder, lang_languageisoname");
1422        queryMap.put(EntityPermission.READ_WRITE,
1423                "SELECT _ALL_ "
1424                + "FROM contactlistfrequencydescriptions "
1425                + "WHERE clstfrqd_clstfrq_contactlistfrequencyid = ? AND clstfrqd_thrutime = ? "
1426                + "FOR UPDATE");
1427        getContactListFrequencyDescriptionsByContactListFrequencyQueries = Collections.unmodifiableMap(queryMap);
1428    }
1429
1430    private List<ContactListFrequencyDescription> getContactListFrequencyDescriptionsByContactListFrequency(ContactListFrequency contactListFrequency, EntityPermission entityPermission) {
1431        return ContactListFrequencyDescriptionFactory.getInstance().getEntitiesFromQuery(entityPermission, getContactListFrequencyDescriptionsByContactListFrequencyQueries,
1432                contactListFrequency, Session.MAX_TIME);
1433    }
1434
1435    public List<ContactListFrequencyDescription> getContactListFrequencyDescriptionsByContactListFrequency(ContactListFrequency contactListFrequency) {
1436        return getContactListFrequencyDescriptionsByContactListFrequency(contactListFrequency, EntityPermission.READ_ONLY);
1437    }
1438
1439    public List<ContactListFrequencyDescription> getContactListFrequencyDescriptionsByContactListFrequencyForUpdate(ContactListFrequency contactListFrequency) {
1440        return getContactListFrequencyDescriptionsByContactListFrequency(contactListFrequency, EntityPermission.READ_WRITE);
1441    }
1442
1443    public String getBestContactListFrequencyDescription(ContactListFrequency contactListFrequency, Language language) {
1444        String description;
1445        ContactListFrequencyDescription contactListFrequencyDescription = getContactListFrequencyDescription(contactListFrequency, language);
1446
1447        if(contactListFrequencyDescription == null && !language.getIsDefault()) {
1448            contactListFrequencyDescription = getContactListFrequencyDescription(contactListFrequency, getPartyControl().getDefaultLanguage());
1449        }
1450
1451        if(contactListFrequencyDescription == null) {
1452            description = contactListFrequency.getLastDetail().getContactListFrequencyName();
1453        } else {
1454            description = contactListFrequencyDescription.getDescription();
1455        }
1456
1457        return description;
1458    }
1459
1460    public ContactListFrequencyDescriptionTransfer getContactListFrequencyDescriptionTransfer(UserVisit userVisit, ContactListFrequencyDescription contactListFrequencyDescription) {
1461        return getContactListTransferCaches(userVisit).getContactListFrequencyDescriptionTransferCache().getContactListFrequencyDescriptionTransfer(contactListFrequencyDescription);
1462    }
1463
1464    public List<ContactListFrequencyDescriptionTransfer> getContactListFrequencyDescriptionTransfersByContactListFrequency(UserVisit userVisit, ContactListFrequency contactListFrequency) {
1465        List<ContactListFrequencyDescription> contactListFrequencyDescriptions = getContactListFrequencyDescriptionsByContactListFrequency(contactListFrequency);
1466        List<ContactListFrequencyDescriptionTransfer> contactListFrequencyDescriptionTransfers = new ArrayList<>(contactListFrequencyDescriptions.size());
1467
1468        contactListFrequencyDescriptions.forEach((contactListFrequencyDescription) -> {
1469            contactListFrequencyDescriptionTransfers.add(getContactListTransferCaches(userVisit).getContactListFrequencyDescriptionTransferCache().getContactListFrequencyDescriptionTransfer(contactListFrequencyDescription));
1470        });
1471
1472        return contactListFrequencyDescriptionTransfers;
1473    }
1474
1475    public void updateContactListFrequencyDescriptionFromValue(ContactListFrequencyDescriptionValue contactListFrequencyDescriptionValue, BasePK updatedBy) {
1476        if(contactListFrequencyDescriptionValue.hasBeenModified()) {
1477            ContactListFrequencyDescription contactListFrequencyDescription = ContactListFrequencyDescriptionFactory.getInstance().getEntityFromPK(EntityPermission.READ_WRITE,
1478                     contactListFrequencyDescriptionValue.getPrimaryKey());
1479
1480            contactListFrequencyDescription.setThruTime(session.START_TIME_LONG);
1481            contactListFrequencyDescription.store();
1482
1483            ContactListFrequency contactListFrequency = contactListFrequencyDescription.getContactListFrequency();
1484            Language language = contactListFrequencyDescription.getLanguage();
1485            String description = contactListFrequencyDescriptionValue.getDescription();
1486
1487            contactListFrequencyDescription = ContactListFrequencyDescriptionFactory.getInstance().create(contactListFrequency, language, description,
1488                    session.START_TIME_LONG, Session.MAX_TIME_LONG);
1489
1490            sendEvent(contactListFrequency.getPrimaryKey(), EventTypes.MODIFY, contactListFrequencyDescription.getPrimaryKey(), EventTypes.MODIFY, updatedBy);
1491        }
1492    }
1493
1494    public void deleteContactListFrequencyDescription(ContactListFrequencyDescription contactListFrequencyDescription, BasePK deletedBy) {
1495        contactListFrequencyDescription.setThruTime(session.START_TIME_LONG);
1496
1497        sendEvent(contactListFrequencyDescription.getContactListFrequencyPK(), EventTypes.MODIFY, contactListFrequencyDescription.getPrimaryKey(), EventTypes.DELETE, deletedBy);
1498
1499    }
1500
1501    public void deleteContactListFrequencyDescriptionsByContactListFrequency(ContactListFrequency contactListFrequency, BasePK deletedBy) {
1502        List<ContactListFrequencyDescription> contactListFrequencyDescriptions = getContactListFrequencyDescriptionsByContactListFrequencyForUpdate(contactListFrequency);
1503
1504        contactListFrequencyDescriptions.forEach((contactListFrequencyDescription) -> 
1505                deleteContactListFrequencyDescription(contactListFrequencyDescription, deletedBy)
1506        );
1507    }
1508
1509    // --------------------------------------------------------------------------------
1510    //   Contact Lists
1511    // --------------------------------------------------------------------------------
1512
1513    public ContactList createContactList(String contactListName, ContactListGroup contactListGroup, ContactListType contactListType,
1514            ContactListFrequency contactListFrequency, WorkflowEntrance defaultPartyContactListStatus, Boolean isDefault, Integer sortOrder, BasePK createdBy) {
1515        ContactList defaultContactList = getDefaultContactList();
1516        boolean defaultFound = defaultContactList != null;
1517
1518        if(defaultFound && isDefault) {
1519            ContactListDetailValue defaultContactListDetailValue = getDefaultContactListDetailValueForUpdate();
1520
1521            defaultContactListDetailValue.setIsDefault(Boolean.FALSE);
1522            updateContactListFromValue(defaultContactListDetailValue, false, createdBy);
1523        } else if(!defaultFound) {
1524            isDefault = Boolean.TRUE;
1525        }
1526
1527        ContactList contactList = ContactListFactory.getInstance().create();
1528        ContactListDetail contactListDetail = ContactListDetailFactory.getInstance().create(contactList, contactListName, contactListGroup, contactListType,
1529            contactListFrequency, defaultPartyContactListStatus, isDefault, sortOrder, session.START_TIME_LONG, Session.MAX_TIME_LONG);
1530
1531        // Convert to R/W
1532        contactList = ContactListFactory.getInstance().getEntityFromPK(EntityPermission.READ_WRITE,
1533                contactList.getPrimaryKey());
1534        contactList.setActiveDetail(contactListDetail);
1535        contactList.setLastDetail(contactListDetail);
1536        contactList.store();
1537
1538        sendEvent(contactList.getPrimaryKey(), EventTypes.CREATE, null, null, createdBy);
1539
1540        return contactList;
1541    }
1542
1543    private static final Map<EntityPermission, String> getContactListByNameQueries;
1544
1545    static {
1546        Map<EntityPermission, String> queryMap = new HashMap<>(2);
1547
1548        queryMap.put(EntityPermission.READ_ONLY,
1549                "SELECT _ALL_ "
1550                + "FROM contactlists, contactlistdetails "
1551                + "WHERE clst_activedetailid = clstdt_contactlistdetailid AND clstdt_contactlistname = ?");
1552        queryMap.put(EntityPermission.READ_WRITE,
1553                "SELECT _ALL_ "
1554                + "FROM contactlists, contactlistdetails "
1555                + "WHERE clst_activedetailid = clstdt_contactlistdetailid AND clstdt_contactlistname = ? "
1556                + "FOR UPDATE");
1557        getContactListByNameQueries = Collections.unmodifiableMap(queryMap);
1558    }
1559
1560    private ContactList getContactListByName(String contactListName, EntityPermission entityPermission) {
1561        return ContactListFactory.getInstance().getEntityFromQuery(entityPermission, getContactListByNameQueries,
1562                contactListName);
1563    }
1564
1565    public ContactList getContactListByName(String contactListName) {
1566        return getContactListByName(contactListName, EntityPermission.READ_ONLY);
1567    }
1568
1569    public ContactList getContactListByNameForUpdate(String contactListName) {
1570        return getContactListByName(contactListName, EntityPermission.READ_WRITE);
1571    }
1572
1573    public ContactListDetailValue getContactListDetailValueForUpdate(ContactList contactList) {
1574        return contactList == null? null: contactList.getLastDetailForUpdate().getContactListDetailValue().clone();
1575    }
1576
1577    public ContactListDetailValue getContactListDetailValueByNameForUpdate(String contactListName) {
1578        return getContactListDetailValueForUpdate(getContactListByNameForUpdate(contactListName));
1579    }
1580
1581    private static final Map<EntityPermission, String> getDefaultContactListQueries;
1582
1583    static {
1584        Map<EntityPermission, String> queryMap = new HashMap<>(2);
1585
1586        queryMap.put(EntityPermission.READ_ONLY,
1587                "SELECT _ALL_ "
1588                + "FROM contactlists, contactlistdetails "
1589                + "WHERE clst_activedetailid = clstdt_contactlistdetailid AND clstdt_isdefault = 1");
1590        queryMap.put(EntityPermission.READ_WRITE,
1591                "SELECT _ALL_ "
1592                + "FROM contactlists, contactlistdetails "
1593                + "WHERE clst_activedetailid = clstdt_contactlistdetailid AND clstdt_isdefault = 1 "
1594                + "FOR UPDATE");
1595        getDefaultContactListQueries = Collections.unmodifiableMap(queryMap);
1596    }
1597
1598    private ContactList getDefaultContactList(EntityPermission entityPermission) {
1599        return ContactListFactory.getInstance().getEntityFromQuery(entityPermission, getDefaultContactListQueries);
1600    }
1601
1602    public ContactList getDefaultContactList() {
1603        return getDefaultContactList(EntityPermission.READ_ONLY);
1604    }
1605
1606    public ContactList getDefaultContactListForUpdate() {
1607        return getDefaultContactList(EntityPermission.READ_WRITE);
1608    }
1609
1610    public ContactListDetailValue getDefaultContactListDetailValueForUpdate() {
1611        return getDefaultContactList(EntityPermission.READ_WRITE).getLastDetailForUpdate().getContactListDetailValue();
1612    }
1613
1614    private static final Map<EntityPermission, String> getContactListsQueries;
1615
1616    static {
1617        Map<EntityPermission, String> queryMap = new HashMap<>(2);
1618
1619        queryMap.put(EntityPermission.READ_ONLY,
1620                "SELECT _ALL_ "
1621                + "FROM contactlists, contactlistdetails "
1622                + "WHERE clst_activedetailid = clstdt_contactlistdetailid "
1623                + "ORDER BY clstdt_sortorder, clstdt_contactlistname");
1624        queryMap.put(EntityPermission.READ_WRITE,
1625                "SELECT _ALL_ "
1626                + "FROM contactlists, contactlistdetails "
1627                + "WHERE clst_activedetailid = clstdt_contactlistdetailid "
1628                + "FOR UPDATE");
1629        getContactListsQueries = Collections.unmodifiableMap(queryMap);
1630    }
1631
1632    private List<ContactList> getContactLists(EntityPermission entityPermission) {
1633        return ContactListFactory.getInstance().getEntitiesFromQuery(entityPermission, getContactListsQueries);
1634    }
1635
1636    public List<ContactList> getContactLists() {
1637        return getContactLists(EntityPermission.READ_ONLY);
1638    }
1639
1640    public List<ContactList> getContactListsForUpdate() {
1641        return getContactLists(EntityPermission.READ_WRITE);
1642    }
1643
1644    private static final Map<EntityPermission, String> getContactListsByContactListGroupQueries;
1645
1646    static {
1647        Map<EntityPermission, String> queryMap = new HashMap<>(2);
1648
1649        queryMap.put(EntityPermission.READ_ONLY,
1650                "SELECT _ALL_ "
1651                + "FROM contactlists, contactlistdetails "
1652                + "WHERE clst_activedetailid = clstdt_contactlistdetailid "
1653                + "AND clstdt_clstgrp_contactlistgroupid = ? "
1654                + "ORDER BY clstdt_sortorder, clstdt_contactlistname");
1655        queryMap.put(EntityPermission.READ_WRITE,
1656                "SELECT _ALL_ "
1657                + "FROM contactlists, contactlistdetails "
1658                + "WHERE clst_activedetailid = clstdt_contactlistdetailid "
1659                + "AND clstdt_clstgrp_contactlistgroupid = ? "
1660                + "FOR UPDATE");
1661        getContactListsByContactListGroupQueries = Collections.unmodifiableMap(queryMap);
1662    }
1663
1664    private List<ContactList> getContactListsByContactListGroup(ContactListGroup contactListGroup, EntityPermission entityPermission) {
1665        return ContactListFactory.getInstance().getEntitiesFromQuery(entityPermission, getContactListsByContactListGroupQueries,
1666                contactListGroup);
1667    }
1668
1669    public List<ContactList> getContactListsByContactListGroup(ContactListGroup contactListGroup) {
1670        return getContactListsByContactListGroup(contactListGroup, EntityPermission.READ_ONLY);
1671    }
1672
1673    public List<ContactList> getContactListsByContactListGroupForUpdate(ContactListGroup contactListGroup) {
1674        return getContactListsByContactListGroup(contactListGroup, EntityPermission.READ_WRITE);
1675    }
1676
1677    private static final Map<EntityPermission, String> getContactListsByContactListTypeQueries;
1678
1679    static {
1680        Map<EntityPermission, String> queryMap = new HashMap<>(2);
1681
1682        queryMap.put(EntityPermission.READ_ONLY,
1683                "SELECT _ALL_ "
1684                + "FROM contactlists, contactlistdetails "
1685                + "WHERE clst_activedetailid = clstdt_contactlistdetailid "
1686                + "AND clstdt_clsttyp_contactlisttypeid = ? "
1687                + "ORDER BY clstdt_sortorder, clstdt_contactlistname");
1688        queryMap.put(EntityPermission.READ_WRITE,
1689                "SELECT _ALL_ "
1690                + "FROM contactlists, contactlistdetails "
1691                + "WHERE clst_activedetailid = clstdt_contactlistdetailid "
1692                + "AND clstdt_clsttyp_contactlisttypeid = ? "
1693                + "FOR UPDATE");
1694        getContactListsByContactListTypeQueries = Collections.unmodifiableMap(queryMap);
1695    }
1696
1697    private List<ContactList> getContactListsByContactListType(ContactListType contactListType, EntityPermission entityPermission) {
1698        return ContactListFactory.getInstance().getEntitiesFromQuery(entityPermission, getContactListsByContactListTypeQueries,
1699                contactListType);
1700    }
1701
1702    public List<ContactList> getContactListsByContactListType(ContactListType contactListType) {
1703        return getContactListsByContactListType(contactListType, EntityPermission.READ_ONLY);
1704    }
1705
1706    public List<ContactList> getContactListsByContactListTypeForUpdate(ContactListType contactListType) {
1707        return getContactListsByContactListType(contactListType, EntityPermission.READ_WRITE);
1708    }
1709
1710    private static final Map<EntityPermission, String> getContactListsByContactListFrequencyQueries;
1711
1712    static {
1713        Map<EntityPermission, String> queryMap = new HashMap<>(2);
1714
1715        queryMap.put(EntityPermission.READ_ONLY,
1716                "SELECT _ALL_ "
1717                + "FROM contactlists, contactlistdetails "
1718                + "WHERE clst_activedetailid = clstdt_contactlistdetailid "
1719                + "AND clstdt_clstfrq_contactlistfrequencyid = ? "
1720                + "ORDER BY clstdt_sortorder, clstdt_contactlistname");
1721        queryMap.put(EntityPermission.READ_WRITE,
1722                "SELECT _ALL_ "
1723                + "FROM contactlists, contactlistdetails "
1724                + "WHERE clst_activedetailid = clstdt_contactlistdetailid "
1725                + "AND clstdt_clstfrq_contactlistfrequencyid = ? "
1726                + "FOR UPDATE");
1727        getContactListsByContactListFrequencyQueries = Collections.unmodifiableMap(queryMap);
1728    }
1729
1730    private List<ContactList> getContactListsByContactListFrequency(ContactListFrequency contactListFrequency, EntityPermission entityPermission) {
1731        return ContactListFactory.getInstance().getEntitiesFromQuery(entityPermission, getContactListsByContactListFrequencyQueries,
1732                contactListFrequency);
1733    }
1734
1735    public List<ContactList> getContactListsByContactListFrequency(ContactListFrequency contactListFrequency) {
1736        return getContactListsByContactListFrequency(contactListFrequency, EntityPermission.READ_ONLY);
1737    }
1738
1739    public List<ContactList> getContactListsByContactListFrequencyForUpdate(ContactListFrequency contactListFrequency) {
1740        return getContactListsByContactListFrequency(contactListFrequency, EntityPermission.READ_WRITE);
1741    }
1742
1743    private static final Map<EntityPermission, String> getContactListsByWorkflowEntranceQueries;
1744
1745    static {
1746        Map<EntityPermission, String> queryMap = new HashMap<>(2);
1747
1748        queryMap.put(EntityPermission.READ_ONLY,
1749                "SELECT _ALL_ "
1750                + "FROM contactlists, contactlistdetails "
1751                + "WHERE clst_activedetailid = clstdt_contactlistdetailid "
1752                + "AND clstdt_wkflen_workflowentranceid = ? "
1753                + "ORDER BY clstdt_sortorder, clstdt_contactlistname");
1754        queryMap.put(EntityPermission.READ_WRITE,
1755                "SELECT _ALL_ "
1756                + "FROM contactlists, contactlistdetails "
1757                + "WHERE clst_activedetailid = clstdt_contactlistdetailid "
1758                + "AND clstdt_wkflen_workflowentranceid = ? "
1759                + "FOR UPDATE");
1760        getContactListsByWorkflowEntranceQueries = Collections.unmodifiableMap(queryMap);
1761    }
1762
1763    private List<ContactList> getContactListsByWorkflowEntrance(WorkflowEntrance workflowEntrance, EntityPermission entityPermission) {
1764        return ContactListFactory.getInstance().getEntitiesFromQuery(entityPermission, getContactListsByWorkflowEntranceQueries,
1765                workflowEntrance);
1766    }
1767
1768    public List<ContactList> getContactListsByWorkflowEntrance(WorkflowEntrance workflowEntrance) {
1769        return getContactListsByWorkflowEntrance(workflowEntrance, EntityPermission.READ_ONLY);
1770    }
1771
1772    public List<ContactList> getContactListsByWorkflowEntranceForUpdate(WorkflowEntrance workflowEntrance) {
1773        return getContactListsByWorkflowEntrance(workflowEntrance, EntityPermission.READ_WRITE);
1774    }
1775
1776    public ContactListChoicesBean getContactListChoices(String defaultContactListChoice, Language language, boolean allowNullChoice) {
1777        List<ContactList> contactLists = getContactLists();
1778        var size = contactLists.size();
1779        var labels = new ArrayList<String>(size);
1780        var values = new ArrayList<String>(size);
1781        String defaultValue = null;
1782
1783        if(allowNullChoice) {
1784            labels.add("");
1785            values.add("");
1786
1787            if(defaultContactListChoice == null) {
1788                defaultValue = "";
1789            }
1790        }
1791
1792        for(var contactList : contactLists) {
1793            ContactListDetail contactListDetail = contactList.getLastDetail();
1794
1795            var label = getBestContactListDescription(contactList, language);
1796            var value = contactListDetail.getContactListName();
1797
1798            labels.add(label == null? value: label);
1799            values.add(value);
1800
1801            var usingDefaultChoice = defaultContactListChoice != null && defaultContactListChoice.equals(value);
1802            if(usingDefaultChoice || (defaultValue == null && contactListDetail.getIsDefault())) {
1803                defaultValue = value;
1804            }
1805        }
1806
1807        return new ContactListChoicesBean(labels, values, defaultValue);
1808    }
1809
1810    public ContactListTransfer getContactListTransfer(UserVisit userVisit, ContactList contactList) {
1811        return getContactListTransferCaches(userVisit).getContactListTransferCache().getContactListTransfer(contactList);
1812    }
1813
1814    public List<ContactListTransfer> getContactListTransfers(UserVisit userVisit) {
1815        List<ContactList> contactLists = getContactLists();
1816        List<ContactListTransfer> contactListTransfers = new ArrayList<>(contactLists.size());
1817        ContactListTransferCache contactListTransferCache = getContactListTransferCaches(userVisit).getContactListTransferCache();
1818
1819        contactLists.forEach((contactList) ->
1820                contactListTransfers.add(contactListTransferCache.getContactListTransfer(contactList))
1821        );
1822
1823        return contactListTransfers;
1824    }
1825
1826    private void updateContactListFromValue(ContactListDetailValue contactListDetailValue, boolean checkDefault, BasePK updatedBy) {
1827        ContactList contactList = ContactListFactory.getInstance().getEntityFromPK(session,
1828                EntityPermission.READ_WRITE, contactListDetailValue.getContactListPK());
1829        ContactListDetail contactListDetail = contactList.getActiveDetailForUpdate();
1830
1831        contactListDetail.setThruTime(session.START_TIME_LONG);
1832        contactListDetail.store();
1833
1834        ContactListPK contactListPK = contactListDetail.getContactListPK();
1835        String contactListName = contactListDetailValue.getContactListName();
1836        ContactListGroupPK contactListGroupPK = contactListDetailValue.getContactListGroupPK();
1837        ContactListTypePK contactListTypePK = contactListDetailValue.getContactListTypePK();
1838        ContactListFrequencyPK contactListFrequencyPK = contactListDetailValue.getContactListFrequencyPK();
1839        WorkflowEntrancePK defaultPartyContactListStatusPK = contactListDetailValue.getDefaultPartyContactListStatusPK();
1840        Boolean isDefault = contactListDetailValue.getIsDefault();
1841        Integer sortOrder = contactListDetailValue.getSortOrder();
1842
1843        if(checkDefault) {
1844            ContactList defaultContactList = getDefaultContactList();
1845            boolean defaultFound = defaultContactList != null && !defaultContactList.equals(contactList);
1846
1847            if(isDefault && defaultFound) {
1848                // If I'm the default, and a default already existed...
1849                ContactListDetailValue defaultContactListDetailValue = getDefaultContactListDetailValueForUpdate();
1850
1851                defaultContactListDetailValue.setIsDefault(Boolean.FALSE);
1852                updateContactListFromValue(defaultContactListDetailValue, false, updatedBy);
1853            } else if(!isDefault && !defaultFound) {
1854                // If I'm not the default, and no other default exists...
1855                isDefault = Boolean.TRUE;
1856            }
1857        }
1858
1859        contactListDetail = ContactListDetailFactory.getInstance().create(contactListPK, contactListName, contactListGroupPK, contactListTypePK,
1860                contactListFrequencyPK, defaultPartyContactListStatusPK, isDefault, sortOrder, session.START_TIME_LONG, Session.MAX_TIME_LONG);
1861
1862        contactList.setActiveDetail(contactListDetail);
1863        contactList.setLastDetail(contactListDetail);
1864        contactList.store();
1865
1866        sendEvent(contactListPK, EventTypes.MODIFY, null, null, updatedBy);
1867    }
1868
1869    public void updateContactListFromValue(ContactListDetailValue contactListDetailValue, BasePK updatedBy) {
1870        updateContactListFromValue(contactListDetailValue, true, updatedBy);
1871    }
1872
1873    public void deleteContactList(ContactList contactList, BasePK deletedBy) {
1874        var letterControl = Session.getModelController(LetterControl.class);
1875        
1876        letterControl.deleteLettersByContactList(contactList, deletedBy);
1877        deletePartyContactListsByContactList(contactList, deletedBy);
1878        deletePartyTypeContactListsByContactList(contactList, deletedBy);
1879        deleteCustomerTypeContactListsByContactList(contactList, deletedBy);
1880        deleteContactListContactMechanismPurposesByContactList(contactList, deletedBy);
1881        deleteContactListDescriptionsByContactList(contactList, deletedBy);
1882
1883        ContactListDetail contactListDetail = contactList.getLastDetailForUpdate();
1884        contactListDetail.setThruTime(session.START_TIME_LONG);
1885        contactList.setActiveDetail(null);
1886        contactList.store();
1887
1888        // Check for default, and pick one if necessary
1889        ContactList defaultContactList = getDefaultContactList();
1890        if(defaultContactList == null) {
1891            List<ContactList> contactLists = getContactListsForUpdate();
1892
1893            if(!contactLists.isEmpty()) {
1894                Iterator<ContactList> iter = contactLists.iterator();
1895                if(iter.hasNext()) {
1896                    defaultContactList = iter.next();
1897                }
1898                ContactListDetailValue contactListDetailValue = Objects.requireNonNull(defaultContactList).getLastDetailForUpdate().getContactListDetailValue().clone();
1899
1900                contactListDetailValue.setIsDefault(Boolean.TRUE);
1901                updateContactListFromValue(contactListDetailValue, false, deletedBy);
1902            }
1903        }
1904
1905        sendEvent(contactList.getPrimaryKey(), EventTypes.DELETE, null, null, deletedBy);
1906    }
1907
1908    public void deleteContactLists(List<ContactList> contactLists, BasePK deletedBy) {
1909        contactLists.forEach((contactList) -> 
1910                deleteContactList(contactList, deletedBy)
1911        );
1912    }
1913
1914    public void deleteContactListsByContactListGroup(ContactListGroup contactListGroup, BasePK deletedBy) {
1915        deleteContactLists(getContactListsByContactListGroupForUpdate(contactListGroup), deletedBy);
1916    }
1917
1918    public void deleteContactListsByContactListType(ContactListType contactListType, BasePK deletedBy) {
1919        deleteContactLists(getContactListsByContactListTypeForUpdate(contactListType), deletedBy);
1920    }
1921
1922    public void deleteContactListsByContactListFrequency(ContactListFrequency contactListFrequency, BasePK deletedBy) {
1923        deleteContactLists(getContactListsByContactListFrequencyForUpdate(contactListFrequency), deletedBy);
1924    }
1925
1926    public void deleteContactListsByWorkflowEntrance(WorkflowEntrance workflowEntrance, BasePK deletedBy) {
1927        deleteContactLists(getContactListsByWorkflowEntranceForUpdate(workflowEntrance), deletedBy);
1928    }
1929
1930    // --------------------------------------------------------------------------------
1931    //   Contact List Descriptions
1932    // --------------------------------------------------------------------------------
1933
1934    public ContactListDescription createContactListDescription(ContactList contactList, Language language, String description,
1935            BasePK createdBy) {
1936        ContactListDescription contactListDescription = ContactListDescriptionFactory.getInstance().create(contactList,
1937                language, description, session.START_TIME_LONG, Session.MAX_TIME_LONG);
1938
1939        sendEvent(contactList.getPrimaryKey(), EventTypes.MODIFY, contactListDescription.getPrimaryKey(), EventTypes.CREATE, createdBy);
1940
1941        return contactListDescription;
1942    }
1943
1944    private static final Map<EntityPermission, String> getContactListDescriptionQueries;
1945
1946    static {
1947        Map<EntityPermission, String> queryMap = new HashMap<>(2);
1948
1949        queryMap.put(EntityPermission.READ_ONLY,
1950                "SELECT _ALL_ "
1951                + "FROM contactlistdescriptions "
1952                + "WHERE clstd_clst_contactlistid = ? AND clstd_lang_languageid = ? AND clstd_thrutime = ?");
1953        queryMap.put(EntityPermission.READ_WRITE,
1954                "SELECT _ALL_ "
1955                + "FROM contactlistdescriptions "
1956                + "WHERE clstd_clst_contactlistid = ? AND clstd_lang_languageid = ? AND clstd_thrutime = ? "
1957                + "FOR UPDATE");
1958        getContactListDescriptionQueries = Collections.unmodifiableMap(queryMap);
1959    }
1960
1961    private ContactListDescription getContactListDescription(ContactList contactList, Language language, EntityPermission entityPermission) {
1962        return ContactListDescriptionFactory.getInstance().getEntityFromQuery(entityPermission, getContactListDescriptionQueries,
1963                contactList, language, Session.MAX_TIME);
1964    }
1965
1966    public ContactListDescription getContactListDescription(ContactList contactList, Language language) {
1967        return getContactListDescription(contactList, language, EntityPermission.READ_ONLY);
1968    }
1969
1970    public ContactListDescription getContactListDescriptionForUpdate(ContactList contactList, Language language) {
1971        return getContactListDescription(contactList, language, EntityPermission.READ_WRITE);
1972    }
1973
1974    public ContactListDescriptionValue getContactListDescriptionValue(ContactListDescription contactListDescription) {
1975        return contactListDescription == null? null: contactListDescription.getContactListDescriptionValue().clone();
1976    }
1977
1978    public ContactListDescriptionValue getContactListDescriptionValueForUpdate(ContactList contactList, Language language) {
1979        return getContactListDescriptionValue(getContactListDescriptionForUpdate(contactList, language));
1980    }
1981
1982    private static final Map<EntityPermission, String> getContactListDescriptionsByContactListQueries;
1983
1984    static {
1985        Map<EntityPermission, String> queryMap = new HashMap<>(2);
1986
1987        queryMap.put(EntityPermission.READ_ONLY,
1988                "SELECT _ALL_ "
1989                + "FROM contactlistdescriptions, languages "
1990                + "WHERE clstd_clst_contactlistid = ? AND clstd_thrutime = ? AND clstd_lang_languageid = lang_languageid "
1991                + "ORDER BY lang_sortorder, lang_languageisoname");
1992        queryMap.put(EntityPermission.READ_WRITE,
1993                "SELECT _ALL_ "
1994                + "FROM contactlistdescriptions "
1995                + "WHERE clstd_clst_contactlistid = ? AND clstd_thrutime = ? "
1996                + "FOR UPDATE");
1997        getContactListDescriptionsByContactListQueries = Collections.unmodifiableMap(queryMap);
1998    }
1999
2000    private List<ContactListDescription> getContactListDescriptionsByContactList(ContactList contactList, EntityPermission entityPermission) {
2001        return ContactListDescriptionFactory.getInstance().getEntitiesFromQuery(entityPermission, getContactListDescriptionsByContactListQueries,
2002                contactList, Session.MAX_TIME);
2003    }
2004
2005    public List<ContactListDescription> getContactListDescriptionsByContactList(ContactList contactList) {
2006        return getContactListDescriptionsByContactList(contactList, EntityPermission.READ_ONLY);
2007    }
2008
2009    public List<ContactListDescription> getContactListDescriptionsByContactListForUpdate(ContactList contactList) {
2010        return getContactListDescriptionsByContactList(contactList, EntityPermission.READ_WRITE);
2011    }
2012
2013    public String getBestContactListDescription(ContactList contactList, Language language) {
2014        String description;
2015        ContactListDescription contactListDescription = getContactListDescription(contactList, language);
2016
2017        if(contactListDescription == null && !language.getIsDefault()) {
2018            contactListDescription = getContactListDescription(contactList, getPartyControl().getDefaultLanguage());
2019        }
2020
2021        if(contactListDescription == null) {
2022            description = contactList.getLastDetail().getContactListName();
2023        } else {
2024            description = contactListDescription.getDescription();
2025        }
2026
2027        return description;
2028    }
2029
2030    public ContactListDescriptionTransfer getContactListDescriptionTransfer(UserVisit userVisit, ContactListDescription contactListDescription) {
2031        return getContactListTransferCaches(userVisit).getContactListDescriptionTransferCache().getContactListDescriptionTransfer(contactListDescription);
2032    }
2033
2034    public List<ContactListDescriptionTransfer> getContactListDescriptionTransfersByContactList(UserVisit userVisit, ContactList contactList) {
2035        List<ContactListDescription> contactListDescriptions = getContactListDescriptionsByContactList(contactList);
2036        List<ContactListDescriptionTransfer> contactListDescriptionTransfers = new ArrayList<>(contactListDescriptions.size());
2037
2038        contactListDescriptions.forEach((contactListDescription) -> {
2039            contactListDescriptionTransfers.add(getContactListTransferCaches(userVisit).getContactListDescriptionTransferCache().getContactListDescriptionTransfer(contactListDescription));
2040        });
2041
2042        return contactListDescriptionTransfers;
2043    }
2044
2045    public void updateContactListDescriptionFromValue(ContactListDescriptionValue contactListDescriptionValue, BasePK updatedBy) {
2046        if(contactListDescriptionValue.hasBeenModified()) {
2047            ContactListDescription contactListDescription = ContactListDescriptionFactory.getInstance().getEntityFromPK(EntityPermission.READ_WRITE,
2048                     contactListDescriptionValue.getPrimaryKey());
2049
2050            contactListDescription.setThruTime(session.START_TIME_LONG);
2051            contactListDescription.store();
2052
2053            ContactList contactList = contactListDescription.getContactList();
2054            Language language = contactListDescription.getLanguage();
2055            String description = contactListDescriptionValue.getDescription();
2056
2057            contactListDescription = ContactListDescriptionFactory.getInstance().create(contactList, language, description,
2058                    session.START_TIME_LONG, Session.MAX_TIME_LONG);
2059
2060            sendEvent(contactList.getPrimaryKey(), EventTypes.MODIFY, contactListDescription.getPrimaryKey(), EventTypes.MODIFY, updatedBy);
2061        }
2062    }
2063
2064    public void deleteContactListDescription(ContactListDescription contactListDescription, BasePK deletedBy) {
2065        contactListDescription.setThruTime(session.START_TIME_LONG);
2066
2067        sendEvent(contactListDescription.getContactListPK(), EventTypes.MODIFY, contactListDescription.getPrimaryKey(), EventTypes.DELETE, deletedBy);
2068
2069    }
2070
2071    public void deleteContactListDescriptionsByContactList(ContactList contactList, BasePK deletedBy) {
2072        List<ContactListDescription> contactListDescriptions = getContactListDescriptionsByContactListForUpdate(contactList);
2073
2074        contactListDescriptions.forEach((contactListDescription) -> 
2075                deleteContactListDescription(contactListDescription, deletedBy)
2076        );
2077    }
2078
2079    // --------------------------------------------------------------------------------
2080    //   Party Contact Lists
2081    // --------------------------------------------------------------------------------
2082    
2083    public PartyContactList createPartyContactList(Party party, ContactList contactList, ContactListContactMechanismPurpose preferredContactListContactMechanismPurpose,
2084            BasePK createdBy) {
2085        PartyContactList partyContactList = PartyContactListFactory.getInstance().create();
2086        PartyContactListDetail partyContactListDetail = PartyContactListDetailFactory.getInstance().create(session, partyContactList, party, contactList,
2087                preferredContactListContactMechanismPurpose, session.START_TIME_LONG, Session.MAX_TIME_LONG);
2088        
2089        // Convert to R/W
2090        partyContactList = PartyContactListFactory.getInstance().getEntityFromPK(EntityPermission.READ_WRITE, partyContactList.getPrimaryKey());
2091        partyContactList.setActiveDetail(partyContactListDetail);
2092        partyContactList.setLastDetail(partyContactListDetail);
2093        partyContactList.store();
2094        
2095        sendEvent(partyContactList.getPrimaryKey(), EventTypes.CREATE, null, null, createdBy);
2096        
2097        return partyContactList;
2098    }
2099    
2100    private static final Map<EntityPermission, String> getPartyContactListQueries;
2101
2102    static {
2103        Map<EntityPermission, String> queryMap = new HashMap<>(2);
2104
2105        queryMap.put(EntityPermission.READ_ONLY,
2106                "SELECT _ALL_ "
2107                + "FROM partycontactlists, partycontactlistdetails "
2108                + "WHERE parclst_activedetailid = parclstdt_partycontactlistdetailid AND parclstdt_par_partyid = ? AND parclstdt_clst_contactlistid = ?");
2109        queryMap.put(EntityPermission.READ_WRITE,
2110                "SELECT _ALL_ "
2111                + "FROM partycontactlists, partycontactlistdetails "
2112                + "WHERE parclst_activedetailid = parclstdt_partycontactlistdetailid AND parclstdt_par_partyid = ? AND parclstdt_clst_contactlistid = ? "
2113                + "FOR UPDATE");
2114        getPartyContactListQueries = Collections.unmodifiableMap(queryMap);
2115    }
2116
2117    private PartyContactList getPartyContactList(Party party, ContactList contactList, EntityPermission entityPermission) {
2118        return PartyContactListFactory.getInstance().getEntityFromQuery(entityPermission, getPartyContactListQueries,
2119                party, contactList);
2120    }
2121    
2122    public PartyContactList getPartyContactList(Party party, ContactList contactList) {
2123        return getPartyContactList(party, contactList, EntityPermission.READ_ONLY);
2124    }
2125    
2126    public PartyContactList getPartyContactListForUpdate(Party party, ContactList contactList) {
2127        return getPartyContactList(party, contactList, EntityPermission.READ_WRITE);
2128    }
2129    
2130    public PartyContactListDetailValue getPartyContactListDetailValueForUpdate(PartyContactList partyContactList) {
2131        return partyContactList == null? null: partyContactList.getLastDetailForUpdate().getPartyContactListDetailValue().clone();
2132    }
2133    
2134    public PartyContactListDetailValue getPartyContactListDetailValueForUpdate(Party party, ContactList contactList) {
2135        return getPartyContactListDetailValueForUpdate(getPartyContactListForUpdate(party, contactList));
2136    }
2137    
2138    private static final Map<EntityPermission, String> getPartyContactListsByPartyQueries;
2139
2140    static {
2141        Map<EntityPermission, String> queryMap = new HashMap<>(2);
2142
2143        queryMap.put(EntityPermission.READ_ONLY,
2144                "SELECT _ALL_ "
2145                + "FROM partycontactlists, partycontactlistdetails, contactlists, contactlistdetails "
2146                + "WHERE parclst_activedetailid = parclstdt_partycontactlistdetailid AND parclstdt_par_partyid = ? "
2147                + "AND parclstdt_clst_contactlistid = clst_contactlistid "
2148                + "AND clst_activedetailid = clstdt_contactlistdetailid "
2149                + "ORDER BY clstdt_sortorder, clstdt_contactlistname");
2150        queryMap.put(EntityPermission.READ_WRITE,
2151                "SELECT _ALL_ "
2152                + "FROM partycontactlists, partycontactlistdetails "
2153                + "WHERE parclst_activedetailid = parclstdt_partycontactlistdetailid AND parclstdt_par_partyid = ? "
2154                + "FOR UPDATE");
2155        getPartyContactListsByPartyQueries = Collections.unmodifiableMap(queryMap);
2156    }
2157
2158    private List<PartyContactList> getPartyContactListsByParty(Party party, EntityPermission entityPermission) {
2159        return PartyContactListFactory.getInstance().getEntitiesFromQuery(entityPermission, getPartyContactListsByPartyQueries,
2160                party);
2161    }
2162
2163    public List<PartyContactList> getPartyContactListsByParty(Party party) {
2164        return getPartyContactListsByParty(party, EntityPermission.READ_ONLY);
2165    }
2166    
2167    public List<PartyContactList> getPartyContactListsByPartyForUpdate(Party party) {
2168        return getPartyContactListsByParty(party, EntityPermission.READ_WRITE);
2169    }
2170    
2171    private static final Map<EntityPermission, String> getPartyContactListsByContactListQueries;
2172
2173    static {
2174        Map<EntityPermission, String> queryMap = new HashMap<>(2);
2175
2176        queryMap.put(EntityPermission.READ_ONLY,
2177                "SELECT _ALL_ "
2178                + "FROM partycontactlists, partycontactlistdetails, parties, partydetails, partytypes "
2179                + "WHERE parclst_activedetailid = parclstdt_partycontactlistdetailid AND parclstdt_clst_contactlistid = ? "
2180                + "AND parclstdt_par_partyid = par_partyid AND par_lastdetailid = pardt_partydetailid "
2181                + "AND pardt_ptyp_partytypeid = ptyp_partytypeid "
2182                + "ORDER BY parclstdt_sortorder, pardt_partyname, ptyp_sortorder, ptyp_partytypename");
2183        queryMap.put(EntityPermission.READ_WRITE,
2184                "SELECT _ALL_ "
2185                + "FROM partycontactlists, partycontactlistdetails "
2186                + "WHERE parclst_activedetailid = parclstdt_partycontactlistdetailid AND parclstdt_clst_contactlistid = ? "
2187                + "FOR UPDATE");
2188        getPartyContactListsByContactListQueries = Collections.unmodifiableMap(queryMap);
2189    }
2190
2191    private List<PartyContactList> getPartyContactListsByContactList(ContactList contactList, EntityPermission entityPermission) {
2192        return PartyContactListFactory.getInstance().getEntitiesFromQuery(entityPermission, getPartyContactListsByContactListQueries,
2193                contactList);
2194    }
2195
2196    public List<PartyContactList> getPartyContactListsByContactList(ContactList contactList) {
2197        return getPartyContactListsByContactList(contactList, EntityPermission.READ_ONLY);
2198    }
2199    
2200    public List<PartyContactList> getPartyContactListsByContactListForUpdate(ContactList contactList) {
2201        return getPartyContactListsByContactList(contactList, EntityPermission.READ_WRITE);
2202    }
2203    
2204    private static final Map<EntityPermission, String> getPartyContactListsByPreferredContactListContactMechanismPurposeQueries;
2205
2206    static {
2207        Map<EntityPermission, String> queryMap = new HashMap<>(2);
2208
2209        queryMap.put(EntityPermission.READ_ONLY,
2210                "SELECT _ALL_ "
2211                + "FROM partycontactlists, partycontactlistdetails "
2212                + "WHERE parclst_activedetailid = parclstdt_partycontactlistdetailid AND parclstdt_preferredcontactlistcontactmechanismpurposeid = ?");
2213        queryMap.put(EntityPermission.READ_WRITE,
2214                "SELECT _ALL_ "
2215                + "FROM partycontactlists, partycontactlistdetails "
2216                + "WHERE parclst_activedetailid = parclstdt_partycontactlistdetailid AND parclstdt_preferredcontactlistcontactmechanismpurposeid = ? "
2217                + "FOR UPDATE");
2218        getPartyContactListsByPreferredContactListContactMechanismPurposeQueries = Collections.unmodifiableMap(queryMap);
2219    }
2220
2221    private List<PartyContactList> getPartyContactListsByPreferredContactListContactMechanismPurpose(ContactListContactMechanismPurpose preferredContactListContactMechanismPurpose,
2222            EntityPermission entityPermission) {
2223        return PartyContactListFactory.getInstance().getEntitiesFromQuery(entityPermission, getPartyContactListsByPreferredContactListContactMechanismPurposeQueries,
2224                preferredContactListContactMechanismPurpose);
2225    }
2226
2227    public List<PartyContactList> getPartyContactListsByPreferredContactListContactMechanismPurpose(ContactListContactMechanismPurpose preferredContactListContactMechanismPurpose) {
2228        return getPartyContactListsByPreferredContactListContactMechanismPurpose(preferredContactListContactMechanismPurpose, EntityPermission.READ_ONLY);
2229    }
2230    
2231    public List<PartyContactList> getPartyContactListsByPreferredContactListContactMechanismPurposeForUpdate(ContactListContactMechanismPurpose preferredContactListContactMechanismPurpose) {
2232        return getPartyContactListsByPreferredContactListContactMechanismPurpose(preferredContactListContactMechanismPurpose, EntityPermission.READ_WRITE);
2233    }
2234    
2235    public List<PartyContactListTransfer> getPartyContactListTransfers(UserVisit userVisit, Collection<PartyContactList> partyContactLists) {
2236        List<PartyContactListTransfer> partyContactListTransfers = new ArrayList<>(partyContactLists.size());
2237        PartyContactListTransferCache partyContactListTransferCache = getContactListTransferCaches(userVisit).getPartyContactListTransferCache();
2238        
2239        partyContactLists.forEach((partyContactList) ->
2240                partyContactListTransfers.add(partyContactListTransferCache.getPartyContactListTransfer(partyContactList))
2241        );
2242        
2243        return partyContactListTransfers;
2244    }
2245    
2246    public List<PartyContactListTransfer> getPartyContactListTransfersByParty(UserVisit userVisit, Party party) {
2247        return getPartyContactListTransfers(userVisit, getPartyContactListsByParty(party));
2248    }
2249    
2250    public List<PartyContactListTransfer> getPartyContactListTransfersByContactList(UserVisit userVisit, ContactList contactList) {
2251        return getPartyContactListTransfers(userVisit, getPartyContactListsByContactList(contactList));
2252    }
2253    
2254    public PartyContactListTransfer getPartyContactListTransfer(UserVisit userVisit, PartyContactList partyContactList) {
2255        return getContactListTransferCaches(userVisit).getPartyContactListTransferCache().getPartyContactListTransfer(partyContactList);
2256    }
2257    
2258    public PartyContactListStatusChoicesBean getPartyContactListStatusChoices(String defaultPartyContactListStatusChoice, Language language,
2259            boolean allowNullChoice, PartyContactList partyContactList, PartyPK partyPK) {
2260        var workflowControl = getWorkflowControl();
2261        PartyContactListStatusChoicesBean partyContactListStatusChoicesBean = new PartyContactListStatusChoicesBean();
2262
2263        if(partyContactList == null) {
2264            workflowControl.getWorkflowEntranceChoices(partyContactListStatusChoicesBean, defaultPartyContactListStatusChoice, language, allowNullChoice,
2265                    workflowControl.getWorkflowByName(PartyContactListStatusConstants.Workflow_PARTY_CONTACT_LIST_STATUS), partyPK);
2266        } else {
2267            EntityInstance entityInstance = getCoreControl().getEntityInstanceByBasePK(partyContactList.getPrimaryKey());
2268            WorkflowEntityStatus workflowEntityStatus = workflowControl.getWorkflowEntityStatusByEntityInstanceUsingNames(PartyContactListStatusConstants.Workflow_PARTY_CONTACT_LIST_STATUS,
2269                    entityInstance);
2270
2271            workflowControl.getWorkflowDestinationChoices(partyContactListStatusChoicesBean, defaultPartyContactListStatusChoice, language, allowNullChoice,
2272                    workflowEntityStatus.getWorkflowStep(), partyPK);
2273        }
2274
2275        return partyContactListStatusChoicesBean;
2276    }
2277
2278    public void setPartyContactListStatus(ExecutionErrorAccumulator eea, PartyContactList partyContactList, String partyContactListStatusChoice,
2279            PartyPK modifiedBy) {
2280        var workflowControl = getWorkflowControl();
2281        EntityInstance entityInstance = getEntityInstanceByBaseEntity(partyContactList);
2282        WorkflowEntityStatus workflowEntityStatus = workflowControl.getWorkflowEntityStatusByEntityInstanceForUpdateUsingNames(PartyContactListStatusConstants.Workflow_PARTY_CONTACT_LIST_STATUS,
2283                entityInstance);
2284        WorkflowDestination workflowDestination = partyContactListStatusChoice == null? null:
2285            workflowControl.getWorkflowDestinationByName(workflowEntityStatus.getWorkflowStep(), partyContactListStatusChoice);
2286
2287        if(workflowDestination != null || partyContactListStatusChoice == null) {
2288            workflowControl.transitionEntityInWorkflow(eea, workflowEntityStatus, workflowDestination, null, modifiedBy);
2289        } else {
2290            eea.addExecutionError(ExecutionErrors.UnknownPartyContactListStatusChoice.name(), partyContactListStatusChoice);
2291        }
2292    }
2293
2294    public void updatePartyContactListFromValue(PartyContactListDetailValue partyContactListDetailValue, BasePK updatedBy) {
2295        if(partyContactListDetailValue.hasBeenModified()) {
2296            PartyContactList partyContactList = PartyContactListFactory.getInstance().getEntityFromPK(EntityPermission.READ_WRITE,
2297                     partyContactListDetailValue.getPartyContactListPK());
2298            PartyContactListDetail partyContactListDetail = partyContactList.getActiveDetailForUpdate();
2299            
2300            partyContactListDetail.setThruTime(session.START_TIME_LONG);
2301            partyContactListDetail.store();
2302            
2303            PartyContactListPK partyContactListPK = partyContactListDetail.getPartyContactListPK();
2304            PartyPK partyPK = partyContactListDetail.getPartyPK(); // Not updated
2305            ContactListPK contactListPK = partyContactListDetail.getContactListPK(); // Not updated
2306            ContactListContactMechanismPurposePK preferredContactListContactMechanismPurposePK = partyContactListDetailValue.getPreferredContactListContactMechanismPurposePK();
2307            
2308            partyContactListDetail = PartyContactListDetailFactory.getInstance().create(partyContactListPK, partyPK, contactListPK,
2309                    preferredContactListContactMechanismPurposePK, session.START_TIME_LONG, Session.MAX_TIME_LONG);
2310            
2311            partyContactList.setActiveDetail(partyContactListDetail);
2312            partyContactList.setLastDetail(partyContactListDetail);
2313            
2314            sendEvent(partyContactList.getPrimaryKey(), EventTypes.MODIFY, null, null, updatedBy);
2315        }
2316    }
2317    
2318    public void clearContactListContactMechanismPurposeFromPartyContactLists(ContactListContactMechanismPurpose preferredContactListContactMechanismPurpose, BasePK clearedBy) {
2319        getPartyContactListsByPreferredContactListContactMechanismPurposeForUpdate(preferredContactListContactMechanismPurpose).stream().map((partyContactList) -> getPartyContactListDetailValueForUpdate(partyContactList)).map((partyContactListDetailValue) -> {
2320            partyContactListDetailValue.setPreferredContactListContactMechanismPurposePK(null);
2321            return partyContactListDetailValue;
2322        }).forEach((partyContactListDetailValue) -> {
2323            updatePartyContactListFromValue(partyContactListDetailValue, clearedBy);
2324        });
2325    }
2326    
2327    public void deletePartyContactList(PartyContactList partyContactList, BasePK deletedBy) {
2328        PartyContactListDetail partyContactListDetail = partyContactList.getLastDetailForUpdate();
2329        partyContactListDetail.setThruTime(session.START_TIME_LONG);
2330        partyContactList.setActiveDetail(null);
2331        partyContactList.store();
2332        
2333        sendEvent(partyContactList.getPrimaryKey(), EventTypes.DELETE, null, null, deletedBy);
2334    }
2335    
2336    public void deletePartyContactListsByParty(Party party, BasePK deletedBy) {
2337        List<PartyContactList> partyContactLists = getPartyContactListsByPartyForUpdate(party);
2338        
2339        partyContactLists.forEach((partyContactList) -> 
2340                deletePartyContactList(partyContactList, deletedBy)
2341        );
2342    }
2343    
2344    public void deletePartyContactListsByContactList(ContactList contactList, BasePK deletedBy) {
2345        List<PartyContactList> partyContactLists = getPartyContactListsByContactListForUpdate(contactList);
2346        
2347        partyContactLists.forEach((partyContactList) -> 
2348                deletePartyContactList(partyContactList, deletedBy)
2349        );
2350    }
2351
2352    // --------------------------------------------------------------------------------
2353    //   Party Type Contact List Groups
2354    // --------------------------------------------------------------------------------
2355    
2356    public PartyTypeContactListGroup createPartyTypeContactListGroup(PartyType partyType, ContactListGroup contactListGroup,
2357            Boolean addWhenCreated, BasePK createdBy) {
2358        PartyTypeContactListGroup partyTypeContactListGroup = PartyTypeContactListGroupFactory.getInstance().create(session,
2359                partyType, contactListGroup, addWhenCreated, session.START_TIME_LONG, Session.MAX_TIME_LONG);
2360        
2361        sendEvent(contactListGroup.getPrimaryKey(), EventTypes.MODIFY, partyTypeContactListGroup.getPrimaryKey(), EventTypes.CREATE, createdBy);
2362        
2363        return partyTypeContactListGroup;
2364    }
2365    
2366    private static final Map<EntityPermission, String> getPartyTypeContactListGroupQueries;
2367
2368    static {
2369        Map<EntityPermission, String> queryMap = new HashMap<>(2);
2370
2371        queryMap.put(EntityPermission.READ_ONLY,
2372                "SELECT _ALL_ "
2373                + "FROM partytypecontactlistgroups "
2374                + "WHERE ptypclstgrp_ptyp_partytypeid = ? AND ptypclstgrp_clstgrp_contactlistgroupid = ? AND ptypclstgrp_thrutime = ?");
2375        queryMap.put(EntityPermission.READ_WRITE,
2376                "SELECT _ALL_ "
2377                + "FROM partytypecontactlistgroups "
2378                + "WHERE ptypclstgrp_ptyp_partytypeid = ? AND ptypclstgrp_clstgrp_contactlistgroupid = ? AND ptypclstgrp_thrutime = ? "
2379                + "FOR UPDATE");
2380        getPartyTypeContactListGroupQueries = Collections.unmodifiableMap(queryMap);
2381    }
2382
2383    private PartyTypeContactListGroup getPartyTypeContactListGroup(PartyType partyType, ContactListGroup contactListGroup, EntityPermission entityPermission) {
2384        return PartyTypeContactListGroupFactory.getInstance().getEntityFromQuery(entityPermission, getPartyTypeContactListGroupQueries,
2385                partyType, contactListGroup, Session.MAX_TIME);
2386    }
2387
2388    public PartyTypeContactListGroup getPartyTypeContactListGroup(PartyType partyType, ContactListGroup contactListGroup) {
2389        return getPartyTypeContactListGroup(partyType, contactListGroup, EntityPermission.READ_ONLY);
2390    }
2391    
2392    public PartyTypeContactListGroup getPartyTypeContactListGroupForUpdate(PartyType partyType, ContactListGroup contactListGroup) {
2393        return getPartyTypeContactListGroup(partyType, contactListGroup, EntityPermission.READ_WRITE);
2394    }
2395    
2396    public PartyTypeContactListGroupValue getPartyTypeContactListGroupValue(PartyTypeContactListGroup partyTypeContactListGroup) {
2397        return partyTypeContactListGroup == null? null: partyTypeContactListGroup.getPartyTypeContactListGroupValue().clone();
2398    }
2399    
2400    public PartyTypeContactListGroupValue getPartyTypeContactListGroupValueForUpdate(PartyType partyType, ContactListGroup contactListGroup) {
2401        return getPartyTypeContactListGroupValue(getPartyTypeContactListGroupForUpdate(partyType, contactListGroup));
2402    }
2403    
2404    private static final Map<EntityPermission, String> getPartyTypeContactListGroupsByPartyTypeQueries;
2405
2406    static {
2407        Map<EntityPermission, String> queryMap = new HashMap<>(2);
2408
2409        queryMap.put(EntityPermission.READ_ONLY,
2410                "SELECT _ALL_ "
2411                + "FROM partytypecontactlistgroups, contactlistgroups, contactlistgroupdetails "
2412                + "WHERE ptypclstgrp_ptyp_partytypeid = ? AND ptypclstgrp_thrutime = ? "
2413                + "AND ptypclstgrp_clstgrp_contactlistgroupid = clstgrp_contactlistgroupid AND clstgrp_lastdetailid = clstgrpdt_contactlistgroupdetailid "
2414                + "ORDER BY clstgrpdt_sortorder, clstgrpdt_contactlistgroupname");
2415        queryMap.put(EntityPermission.READ_WRITE,
2416                "SELECT _ALL_ "
2417                + "FROM partytypecontactlistgroups "
2418                + "WHERE ptypclstgrp_ptyp_partytypeid = ? AND ptypclstgrp_thrutime = ? "
2419                + "FOR UPDATE");
2420        getPartyTypeContactListGroupsByPartyTypeQueries = Collections.unmodifiableMap(queryMap);
2421    }
2422
2423    private List<PartyTypeContactListGroup> getPartyTypeContactListGroupsByPartyType(PartyType partyType, EntityPermission entityPermission) {
2424        return PartyTypeContactListGroupFactory.getInstance().getEntitiesFromQuery(entityPermission, getPartyTypeContactListGroupsByPartyTypeQueries,
2425                partyType, Session.MAX_TIME);
2426    }
2427
2428    public List<PartyTypeContactListGroup> getPartyTypeContactListGroupsByPartyType(PartyType partyType) {
2429        return getPartyTypeContactListGroupsByPartyType(partyType, EntityPermission.READ_ONLY);
2430    }
2431    
2432    public List<PartyTypeContactListGroup> getPartyTypeContactListGroupsByPartyTypeForUpdate(PartyType partyType) {
2433        return getPartyTypeContactListGroupsByPartyType(partyType, EntityPermission.READ_WRITE);
2434    }
2435    
2436    private static final Map<EntityPermission, String> getPartyTypeContactListGroupsByContactListGroupQueries;
2437
2438    static {
2439        Map<EntityPermission, String> queryMap = new HashMap<>(2);
2440
2441        queryMap.put(EntityPermission.READ_ONLY,
2442                "SELECT _ALL_ "
2443                + "FROM partytypecontactlistgroups, partytypes "
2444                + "WHERE ptypclstgrp_clstgrp_contactlistgroupid = ? AND ptypclstgrp_thrutime = ? "
2445                + "AND ptypclstgrp_ptyp_partytypeid = ptyp_partytypeid "
2446                + "ORDER BY ptyp_sortorder, ptyp_partytypename");
2447        queryMap.put(EntityPermission.READ_WRITE,
2448                "SELECT _ALL_ "
2449                + "FROM partytypecontactlistgroups "
2450                + "WHERE ptypclstgrp_clstgrp_contactlistgroupid = ? AND ptypclstgrp_thrutime = ? "
2451                + "FOR UPDATE");
2452        getPartyTypeContactListGroupsByContactListGroupQueries = Collections.unmodifiableMap(queryMap);
2453    }
2454
2455    private List<PartyTypeContactListGroup> getPartyTypeContactListGroupsByContactListGroup(ContactListGroup contactListGroup, EntityPermission entityPermission) {
2456        return PartyTypeContactListGroupFactory.getInstance().getEntitiesFromQuery(entityPermission, getPartyTypeContactListGroupsByContactListGroupQueries,
2457                contactListGroup, Session.MAX_TIME);
2458    }
2459
2460    public List<PartyTypeContactListGroup> getPartyTypeContactListGroupsByContactListGroup(ContactListGroup contactListGroup) {
2461        return getPartyTypeContactListGroupsByContactListGroup(contactListGroup, EntityPermission.READ_ONLY);
2462    }
2463    
2464    public List<PartyTypeContactListGroup> getPartyTypeContactListGroupsByContactListGroupForUpdate(ContactListGroup contactListGroup) {
2465        return getPartyTypeContactListGroupsByContactListGroup(contactListGroup, EntityPermission.READ_WRITE);
2466    }
2467    
2468    public List<PartyTypeContactListGroupTransfer> getPartyTypeContactListGroupTransfers(UserVisit userVisit, Collection<PartyTypeContactListGroup> partyTypeContactListGroups) {
2469        List<PartyTypeContactListGroupTransfer> partyTypeContactListGroupTransfers = new ArrayList<>(partyTypeContactListGroups.size());
2470        PartyTypeContactListGroupTransferCache partyTypeContactListGroupTransferCache = getContactListTransferCaches(userVisit).getPartyTypeContactListGroupTransferCache();
2471        
2472        partyTypeContactListGroups.forEach((partyTypeContactListGroup) ->
2473                partyTypeContactListGroupTransfers.add(partyTypeContactListGroupTransferCache.getPartyTypeContactListGroupTransfer(partyTypeContactListGroup))
2474        );
2475        
2476        return partyTypeContactListGroupTransfers;
2477    }
2478    
2479    public List<PartyTypeContactListGroupTransfer> getPartyTypeContactListGroupTransfersByPartyType(UserVisit userVisit, PartyType partyType) {
2480        return getPartyTypeContactListGroupTransfers(userVisit, getPartyTypeContactListGroupsByPartyType(partyType));
2481    }
2482    
2483    public List<PartyTypeContactListGroupTransfer> getPartyTypeContactListGroupTransfersByContactListGroup(UserVisit userVisit, ContactListGroup contactListGroup) {
2484        return getPartyTypeContactListGroupTransfers(userVisit, getPartyTypeContactListGroupsByContactListGroup(contactListGroup));
2485    }
2486    
2487    public PartyTypeContactListGroupTransfer getPartyTypeContactListGroupTransfer(UserVisit userVisit, PartyTypeContactListGroup partyTypeContactListGroup) {
2488        return getContactListTransferCaches(userVisit).getPartyTypeContactListGroupTransferCache().getPartyTypeContactListGroupTransfer(partyTypeContactListGroup);
2489    }
2490    
2491    public void updatePartyTypeContactListGroupFromValue(PartyTypeContactListGroupValue partyTypeContactListGroupValue, BasePK updatedBy) {
2492        if(partyTypeContactListGroupValue.hasBeenModified()) {
2493            PartyTypeContactListGroup partyTypeContactListGroup = PartyTypeContactListGroupFactory.getInstance().getEntityFromPK(EntityPermission.READ_WRITE,
2494                     partyTypeContactListGroupValue.getPrimaryKey());
2495            
2496            partyTypeContactListGroup.setThruTime(session.START_TIME_LONG);
2497            partyTypeContactListGroup.store();
2498            
2499            PartyTypePK partyTypePK = partyTypeContactListGroup.getPartyType().getPrimaryKey(); // Not Updated
2500            ContactListGroupPK contactListGroupPK = partyTypeContactListGroup.getContactListGroupPK(); // Not Updated
2501            Boolean addWhenCreated = partyTypeContactListGroupValue.getAddWhenCreated();
2502            
2503            partyTypeContactListGroup = PartyTypeContactListGroupFactory.getInstance().create(partyTypePK, contactListGroupPK, addWhenCreated,
2504                    session.START_TIME_LONG, Session.MAX_TIME_LONG);
2505            
2506            sendEvent(contactListGroupPK, EventTypes.MODIFY, partyTypeContactListGroup.getPrimaryKey(), EventTypes.MODIFY, updatedBy);
2507        }
2508    }
2509    
2510    public void deletePartyTypeContactListGroup(PartyTypeContactListGroup partyTypeContactListGroup, BasePK deletedBy) {
2511        partyTypeContactListGroup.setThruTime(session.START_TIME_LONG);
2512        partyTypeContactListGroup.store();
2513        
2514        sendEvent(partyTypeContactListGroup.getContactListGroupPK(), EventTypes.MODIFY, partyTypeContactListGroup.getPrimaryKey(), EventTypes.DELETE, deletedBy);
2515    }
2516    
2517    public void deletePartyTypeContactListGroups(List<PartyTypeContactListGroup> partyTypeContactListGroups, BasePK deletedBy) {
2518        partyTypeContactListGroups.forEach((partyTypeContactListGroup) -> 
2519                deletePartyTypeContactListGroup(partyTypeContactListGroup, deletedBy)
2520        );
2521    }
2522    
2523    public void deletePartyTypeContactListGroupsByPartyType(PartyType partyType, BasePK deletedBy) {
2524        deletePartyTypeContactListGroups(getPartyTypeContactListGroupsByPartyTypeForUpdate(partyType), deletedBy);
2525    }
2526    
2527    public void deletePartyTypeContactListGroupsByContactListGroup(ContactListGroup contactListGroup, BasePK deletedBy) {
2528        deletePartyTypeContactListGroups(getPartyTypeContactListGroupsByContactListGroupForUpdate(contactListGroup), deletedBy);
2529    }
2530    
2531    // --------------------------------------------------------------------------------
2532    //   Party Type Contact Lists
2533    // --------------------------------------------------------------------------------
2534    
2535    public PartyTypeContactList createPartyTypeContactList(PartyType partyType, ContactList contactList, Boolean addWhenCreated, BasePK createdBy) {
2536        PartyTypeContactList partyTypeContactList = PartyTypeContactListFactory.getInstance().create(session, partyType, contactList, addWhenCreated,
2537                session.START_TIME_LONG, Session.MAX_TIME_LONG);
2538        
2539        sendEvent(contactList.getPrimaryKey(), EventTypes.MODIFY, partyTypeContactList.getPrimaryKey(), EventTypes.CREATE, createdBy);
2540        
2541        return partyTypeContactList;
2542    }
2543    
2544    private static final Map<EntityPermission, String> getPartyTypeContactListQueries;
2545
2546    static {
2547        Map<EntityPermission, String> queryMap = new HashMap<>(2);
2548
2549        queryMap.put(EntityPermission.READ_ONLY,
2550                "SELECT _ALL_ "
2551                + "FROM partytypecontactlists "
2552                + "WHERE ptypclst_ptyp_partytypeid = ? AND ptypclst_clst_contactlistid = ? AND ptypclst_thrutime = ?");
2553        queryMap.put(EntityPermission.READ_WRITE,
2554                "SELECT _ALL_ "
2555                + "FROM partytypecontactlists "
2556                + "WHERE ptypclst_ptyp_partytypeid = ? AND ptypclst_clst_contactlistid = ? AND ptypclst_thrutime = ? "
2557                + "FOR UPDATE");
2558        getPartyTypeContactListQueries = Collections.unmodifiableMap(queryMap);
2559    }
2560
2561    private PartyTypeContactList getPartyTypeContactList(PartyType partyType, ContactList contactList, EntityPermission entityPermission) {
2562        return PartyTypeContactListFactory.getInstance().getEntityFromQuery(entityPermission, getPartyTypeContactListQueries,
2563                partyType, contactList, Session.MAX_TIME);
2564    }
2565
2566    public PartyTypeContactList getPartyTypeContactList(PartyType partyType, ContactList contactList) {
2567        return getPartyTypeContactList(partyType, contactList, EntityPermission.READ_ONLY);
2568    }
2569    
2570    public PartyTypeContactList getPartyTypeContactListForUpdate(PartyType partyType, ContactList contactList) {
2571        return getPartyTypeContactList(partyType, contactList, EntityPermission.READ_WRITE);
2572    }
2573    
2574    public PartyTypeContactListValue getPartyTypeContactListValue(PartyTypeContactList partyTypeContactList) {
2575        return partyTypeContactList == null? null: partyTypeContactList.getPartyTypeContactListValue().clone();
2576    }
2577    
2578    public PartyTypeContactListValue getPartyTypeContactListValueForUpdate(PartyType partyType, ContactList contactList) {
2579        return getPartyTypeContactListValue(getPartyTypeContactListForUpdate(partyType, contactList));
2580    }
2581    
2582    private static final Map<EntityPermission, String> getPartyTypeContactListsByPartyTypeQueries;
2583
2584    static {
2585        Map<EntityPermission, String> queryMap = new HashMap<>(2);
2586
2587        queryMap.put(EntityPermission.READ_ONLY,
2588                "SELECT _ALL_ "
2589                + "FROM partytypecontactlists, contactlists, contactlistdetails "
2590                + "WHERE ptypclst_ptyp_partytypeid = ? AND ptypclst_thrutime = ? "
2591                + "AND ptypclst_clst_contactlistid = clst_contactlistid AND clst_lastdetailid = clstdt_contactlistdetailid "
2592                + "ORDER BY clstdt_sortorder, clstdt_contactlistname");
2593        queryMap.put(EntityPermission.READ_WRITE,
2594                "SELECT _ALL_ "
2595                + "FROM partytypecontactlists "
2596                + "WHERE ptypclst_ptyp_partytypeid = ? AND ptypclst_thrutime = ? "
2597                + "FOR UPDATE");
2598        getPartyTypeContactListsByPartyTypeQueries = Collections.unmodifiableMap(queryMap);
2599    }
2600
2601    private List<PartyTypeContactList> getPartyTypeContactListsByPartyType(PartyType partyType, EntityPermission entityPermission) {
2602        return PartyTypeContactListFactory.getInstance().getEntitiesFromQuery(entityPermission, getPartyTypeContactListsByPartyTypeQueries,
2603                partyType, Session.MAX_TIME);
2604    }
2605
2606    public List<PartyTypeContactList> getPartyTypeContactListsByPartyType(PartyType partyType) {
2607        return getPartyTypeContactListsByPartyType(partyType, EntityPermission.READ_ONLY);
2608    }
2609    
2610    public List<PartyTypeContactList> getPartyTypeContactListsByPartyTypeForUpdate(PartyType partyType) {
2611        return getPartyTypeContactListsByPartyType(partyType, EntityPermission.READ_WRITE);
2612    }
2613    
2614    private static final Map<EntityPermission, String> getPartyTypeContactListsByContactListQueries;
2615
2616    static {
2617        Map<EntityPermission, String> queryMap = new HashMap<>(2);
2618
2619        queryMap.put(EntityPermission.READ_ONLY,
2620                "SELECT _ALL_ "
2621                + "FROM partytypecontactlists, partytypes "
2622                + "WHERE ptypclst_clst_contactlistid = ? AND ptypclst_thrutime = ? "
2623                + "AND ptypclst_ptyp_partytypeid = ptyp_partytypeid "
2624                + "ORDER BY ptyp_sortorder, ptyp_partytypename");
2625        queryMap.put(EntityPermission.READ_WRITE,
2626                "SELECT _ALL_ "
2627                + "FROM partytypecontactlists "
2628                + "WHERE ptypclst_clst_contactlistid = ? AND ptypclst_thrutime = ? "
2629                + "FOR UPDATE");
2630        getPartyTypeContactListsByContactListQueries = Collections.unmodifiableMap(queryMap);
2631    }
2632
2633    private List<PartyTypeContactList> getPartyTypeContactListsByContactList(ContactList contactList, EntityPermission entityPermission) {
2634        return PartyTypeContactListFactory.getInstance().getEntitiesFromQuery(entityPermission, getPartyTypeContactListsByContactListQueries,
2635                contactList, Session.MAX_TIME);
2636    }
2637
2638    public List<PartyTypeContactList> getPartyTypeContactListsByContactList(ContactList contactList) {
2639        return getPartyTypeContactListsByContactList(contactList, EntityPermission.READ_ONLY);
2640    }
2641    
2642    public List<PartyTypeContactList> getPartyTypeContactListsByContactListForUpdate(ContactList contactList) {
2643        return getPartyTypeContactListsByContactList(contactList, EntityPermission.READ_WRITE);
2644    }
2645    
2646    public List<PartyTypeContactListTransfer> getPartyTypeContactListTransfers(UserVisit userVisit, Collection<PartyTypeContactList> partyTypeContactLists) {
2647        List<PartyTypeContactListTransfer> partyTypeContactListTransfers = new ArrayList<>(partyTypeContactLists.size());
2648        PartyTypeContactListTransferCache partyTypeContactListTransferCache = getContactListTransferCaches(userVisit).getPartyTypeContactListTransferCache();
2649        
2650        partyTypeContactLists.forEach((partyTypeContactList) ->
2651                partyTypeContactListTransfers.add(partyTypeContactListTransferCache.getPartyTypeContactListTransfer(partyTypeContactList))
2652        );
2653        
2654        return partyTypeContactListTransfers;
2655    }
2656    
2657    public List<PartyTypeContactListTransfer> getPartyTypeContactListTransfersByPartyType(UserVisit userVisit, PartyType partyType) {
2658        return getPartyTypeContactListTransfers(userVisit, getPartyTypeContactListsByPartyType(partyType));
2659    }
2660    
2661    public List<PartyTypeContactListTransfer> getPartyTypeContactListTransfersByContactList(UserVisit userVisit, ContactList contactList) {
2662        return getPartyTypeContactListTransfers(userVisit, getPartyTypeContactListsByContactList(contactList));
2663    }
2664    
2665    public PartyTypeContactListTransfer getPartyTypeContactListTransfer(UserVisit userVisit, PartyTypeContactList partyTypeContactList) {
2666        return getContactListTransferCaches(userVisit).getPartyTypeContactListTransferCache().getPartyTypeContactListTransfer(partyTypeContactList);
2667    }
2668    
2669    public void updatePartyTypeContactListFromValue(PartyTypeContactListValue partyTypeContactListValue, BasePK updatedBy) {
2670        if(partyTypeContactListValue.hasBeenModified()) {
2671            PartyTypeContactList partyTypeContactList = PartyTypeContactListFactory.getInstance().getEntityFromPK(EntityPermission.READ_WRITE,
2672                     partyTypeContactListValue.getPrimaryKey());
2673            
2674            partyTypeContactList.setThruTime(session.START_TIME_LONG);
2675            partyTypeContactList.store();
2676            
2677            PartyTypePK partyTypePK = partyTypeContactList.getPartyType().getPrimaryKey(); // Not Updated
2678            ContactListPK contactListPK = partyTypeContactList.getContactListPK(); // Not Updated
2679            Boolean addWhenCreated = partyTypeContactListValue.getAddWhenCreated();
2680            
2681            partyTypeContactList = PartyTypeContactListFactory.getInstance().create(partyTypePK, contactListPK, addWhenCreated, session.START_TIME_LONG,
2682                    Session.MAX_TIME_LONG);
2683            
2684            sendEvent(contactListPK, EventTypes.MODIFY, partyTypeContactList.getPrimaryKey(), EventTypes.MODIFY, updatedBy);
2685        }
2686    }
2687    
2688    public void deletePartyTypeContactList(PartyTypeContactList partyTypeContactList, BasePK deletedBy) {
2689        partyTypeContactList.setThruTime(session.START_TIME_LONG);
2690        partyTypeContactList.store();
2691        
2692        sendEvent(partyTypeContactList.getContactListPK(), EventTypes.MODIFY, partyTypeContactList.getPrimaryKey(), EventTypes.DELETE, deletedBy);
2693    }
2694    
2695    public void deletePartyTypeContactLists(List<PartyTypeContactList> partyTypeContactLists, BasePK deletedBy) {
2696        partyTypeContactLists.forEach((partyTypeContactList) -> 
2697                deletePartyTypeContactList(partyTypeContactList, deletedBy)
2698        );
2699    }
2700    
2701    public void deletePartyTypeContactListsByPartyType(PartyType partyType, BasePK deletedBy) {
2702        deletePartyTypeContactLists(getPartyTypeContactListsByPartyTypeForUpdate(partyType), deletedBy);
2703    }
2704    
2705    public void deletePartyTypeContactListsByContactList(ContactList contactList, BasePK deletedBy) {
2706        deletePartyTypeContactLists(getPartyTypeContactListsByContactListForUpdate(contactList), deletedBy);
2707    }
2708    
2709    // --------------------------------------------------------------------------------
2710    //   Customer Type Contact List Groups
2711    // --------------------------------------------------------------------------------
2712
2713    public CustomerTypeContactListGroup createCustomerTypeContactListGroup(CustomerType customerType, ContactListGroup contactListGroup,
2714            Boolean addWhenCreated, BasePK createdBy) {
2715        CustomerTypeContactListGroup customerTypeContactListGroup = CustomerTypeContactListGroupFactory.getInstance().create(session,
2716                customerType, contactListGroup, addWhenCreated, session.START_TIME_LONG, Session.MAX_TIME_LONG);
2717
2718        sendEvent(contactListGroup.getPrimaryKey(), EventTypes.MODIFY, customerTypeContactListGroup.getPrimaryKey(), EventTypes.CREATE, createdBy);
2719
2720        return customerTypeContactListGroup;
2721    }
2722
2723    private static final Map<EntityPermission, String> getCustomerTypeContactListGroupQueries;
2724
2725    static {
2726        Map<EntityPermission, String> queryMap = new HashMap<>(2);
2727
2728        queryMap.put(EntityPermission.READ_ONLY,
2729                "SELECT _ALL_ "
2730                + "FROM customertypecontactlistgroups "
2731                + "WHERE cutyclstgrp_cuty_customertypeid = ? AND cutyclstgrp_clstgrp_contactlistgroupid = ? AND cutyclstgrp_thrutime = ?");
2732        queryMap.put(EntityPermission.READ_WRITE,
2733                "SELECT _ALL_ "
2734                + "FROM customertypecontactlistgroups "
2735                + "WHERE cutyclstgrp_cuty_customertypeid = ? AND cutyclstgrp_clstgrp_contactlistgroupid = ? AND cutyclstgrp_thrutime = ? "
2736                + "FOR UPDATE");
2737        getCustomerTypeContactListGroupQueries = Collections.unmodifiableMap(queryMap);
2738    }
2739
2740    private CustomerTypeContactListGroup getCustomerTypeContactListGroup(CustomerType customerType, ContactListGroup contactListGroup, EntityPermission entityPermission) {
2741        return CustomerTypeContactListGroupFactory.getInstance().getEntityFromQuery(entityPermission, getCustomerTypeContactListGroupQueries,
2742                customerType, contactListGroup, Session.MAX_TIME);
2743    }
2744
2745    public CustomerTypeContactListGroup getCustomerTypeContactListGroup(CustomerType customerType, ContactListGroup contactListGroup) {
2746        return getCustomerTypeContactListGroup(customerType, contactListGroup, EntityPermission.READ_ONLY);
2747    }
2748
2749    public CustomerTypeContactListGroup getCustomerTypeContactListGroupForUpdate(CustomerType customerType, ContactListGroup contactListGroup) {
2750        return getCustomerTypeContactListGroup(customerType, contactListGroup, EntityPermission.READ_WRITE);
2751    }
2752
2753    public CustomerTypeContactListGroupValue getCustomerTypeContactListGroupValue(CustomerTypeContactListGroup customerTypeContactListGroup) {
2754        return customerTypeContactListGroup == null? null: customerTypeContactListGroup.getCustomerTypeContactListGroupValue().clone();
2755    }
2756
2757    public CustomerTypeContactListGroupValue getCustomerTypeContactListGroupValueForUpdate(CustomerType customerType, ContactListGroup contactListGroup) {
2758        return getCustomerTypeContactListGroupValue(getCustomerTypeContactListGroupForUpdate(customerType, contactListGroup));
2759    }
2760
2761    private static final Map<EntityPermission, String> getCustomerTypeContactListGroupsByCustomerTypeQueries;
2762
2763    static {
2764        Map<EntityPermission, String> queryMap = new HashMap<>(2);
2765
2766        queryMap.put(EntityPermission.READ_ONLY,
2767                "SELECT _ALL_ "
2768                + "FROM customertypecontactlistgroups, contactlistgroups, contactlistgroupdetails "
2769                + "WHERE cutyclstgrp_cuty_customertypeid = ? AND cutyclstgrp_thrutime = ? "
2770                + "AND cutyclstgrp_clstgrp_contactlistgroupid = clstgrp_contactlistgroupid AND clstgrp_lastdetailid = clstgrpdt_contactlistgroupdetailid "
2771                + "ORDER BY clstgrpdt_sortorder, clstgrpdt_contactlistgroupname");
2772        queryMap.put(EntityPermission.READ_WRITE,
2773                "SELECT _ALL_ "
2774                + "FROM customertypecontactlistgroups "
2775                + "WHERE cutyclstgrp_cuty_customertypeid = ? AND cutyclstgrp_thrutime = ? "
2776                + "FOR UPDATE");
2777        getCustomerTypeContactListGroupsByCustomerTypeQueries = Collections.unmodifiableMap(queryMap);
2778    }
2779
2780    private List<CustomerTypeContactListGroup> getCustomerTypeContactListGroupsByCustomerType(CustomerType customerType, EntityPermission entityPermission) {
2781        return CustomerTypeContactListGroupFactory.getInstance().getEntitiesFromQuery(entityPermission, getCustomerTypeContactListGroupsByCustomerTypeQueries,
2782                customerType, Session.MAX_TIME);
2783    }
2784
2785    public List<CustomerTypeContactListGroup> getCustomerTypeContactListGroupsByCustomerType(CustomerType customerType) {
2786        return getCustomerTypeContactListGroupsByCustomerType(customerType, EntityPermission.READ_ONLY);
2787    }
2788
2789    public List<CustomerTypeContactListGroup> getCustomerTypeContactListGroupsByCustomerTypeForUpdate(CustomerType customerType) {
2790        return getCustomerTypeContactListGroupsByCustomerType(customerType, EntityPermission.READ_WRITE);
2791    }
2792
2793    private static final Map<EntityPermission, String> getCustomerTypeContactListGroupsByContactListGroupQueries;
2794
2795    static {
2796        Map<EntityPermission, String> queryMap = new HashMap<>(2);
2797
2798        queryMap.put(EntityPermission.READ_ONLY,
2799                "SELECT _ALL_ "
2800                + "FROM customertypecontactlistgroups, customertypes, customertypedetails "
2801                + "WHERE cutyclstgrp_clstgrp_contactlistgroupid = ? AND cutyclstgrp_thrutime = ? "
2802                + "AND cutyclstgrp_cuty_customertypeid = cuty_customertypeid AND cuty_lastdetailid = cutydt_customertypedetailid "
2803                + "ORDER BY cutydt_sortorder, cutydt_customertypename");
2804        queryMap.put(EntityPermission.READ_WRITE,
2805                "SELECT _ALL_ "
2806                + "FROM customertypecontactlistgroups "
2807                + "WHERE cutyclstgrp_clstgrp_contactlistgroupid = ? AND cutyclstgrp_thrutime = ? "
2808                + "FOR UPDATE");
2809        getCustomerTypeContactListGroupsByContactListGroupQueries = Collections.unmodifiableMap(queryMap);
2810    }
2811
2812    private List<CustomerTypeContactListGroup> getCustomerTypeContactListGroupsByContactListGroup(ContactListGroup contactListGroup, EntityPermission entityPermission) {
2813        return CustomerTypeContactListGroupFactory.getInstance().getEntitiesFromQuery(entityPermission, getCustomerTypeContactListGroupsByContactListGroupQueries,
2814                contactListGroup, Session.MAX_TIME);
2815    }
2816
2817    public List<CustomerTypeContactListGroup> getCustomerTypeContactListGroupsByContactListGroup(ContactListGroup contactListGroup) {
2818        return getCustomerTypeContactListGroupsByContactListGroup(contactListGroup, EntityPermission.READ_ONLY);
2819    }
2820
2821    public List<CustomerTypeContactListGroup> getCustomerTypeContactListGroupsByContactListGroupForUpdate(ContactListGroup contactListGroup) {
2822        return getCustomerTypeContactListGroupsByContactListGroup(contactListGroup, EntityPermission.READ_WRITE);
2823    }
2824
2825    public List<CustomerTypeContactListGroupTransfer> getCustomerTypeContactListGroupTransfers(UserVisit userVisit, Collection<CustomerTypeContactListGroup> customerTypeContactListGroups) {
2826        List<CustomerTypeContactListGroupTransfer> customerTypeContactListGroupTransfers = new ArrayList<>(customerTypeContactListGroups.size());
2827        CustomerTypeContactListGroupTransferCache customerTypeContactListGroupTransferCache = getContactListTransferCaches(userVisit).getCustomerTypeContactListGroupTransferCache();
2828
2829        customerTypeContactListGroups.forEach((customerTypeContactListGroup) ->
2830                customerTypeContactListGroupTransfers.add(customerTypeContactListGroupTransferCache.getCustomerTypeContactListGroupTransfer(customerTypeContactListGroup))
2831        );
2832
2833        return customerTypeContactListGroupTransfers;
2834    }
2835
2836    public List<CustomerTypeContactListGroupTransfer> getCustomerTypeContactListGroupTransfersByCustomerType(UserVisit userVisit, CustomerType customerType) {
2837        return getCustomerTypeContactListGroupTransfers(userVisit, getCustomerTypeContactListGroupsByCustomerType(customerType));
2838    }
2839
2840    public List<CustomerTypeContactListGroupTransfer> getCustomerTypeContactListGroupTransfersByContactListGroup(UserVisit userVisit, ContactListGroup contactListGroup) {
2841        return getCustomerTypeContactListGroupTransfers(userVisit, getCustomerTypeContactListGroupsByContactListGroup(contactListGroup));
2842    }
2843
2844    public CustomerTypeContactListGroupTransfer getCustomerTypeContactListGroupTransfer(UserVisit userVisit, CustomerTypeContactListGroup customerTypeContactListGroup) {
2845        return getContactListTransferCaches(userVisit).getCustomerTypeContactListGroupTransferCache().getCustomerTypeContactListGroupTransfer(customerTypeContactListGroup);
2846    }
2847
2848    public void updateCustomerTypeContactListGroupFromValue(CustomerTypeContactListGroupValue customerTypeContactListGroupValue, BasePK updatedBy) {
2849        if(customerTypeContactListGroupValue.hasBeenModified()) {
2850            CustomerTypeContactListGroup customerTypeContactListGroup = CustomerTypeContactListGroupFactory.getInstance().getEntityFromPK(EntityPermission.READ_WRITE,
2851                     customerTypeContactListGroupValue.getPrimaryKey());
2852
2853            customerTypeContactListGroup.setThruTime(session.START_TIME_LONG);
2854            customerTypeContactListGroup.store();
2855
2856            CustomerTypePK customerTypePK = customerTypeContactListGroup.getCustomerType().getPrimaryKey(); // Not Updated
2857            ContactListGroupPK contactListGroupPK = customerTypeContactListGroup.getContactListGroupPK(); // Not Updated
2858            Boolean addWhenCreated = customerTypeContactListGroupValue.getAddWhenCreated();
2859
2860            customerTypeContactListGroup = CustomerTypeContactListGroupFactory.getInstance().create(customerTypePK, contactListGroupPK, addWhenCreated,
2861                    session.START_TIME_LONG, Session.MAX_TIME_LONG);
2862
2863            sendEvent(contactListGroupPK, EventTypes.MODIFY, customerTypeContactListGroup.getPrimaryKey(), EventTypes.MODIFY, updatedBy);
2864        }
2865    }
2866
2867    public void deleteCustomerTypeContactListGroup(CustomerTypeContactListGroup customerTypeContactListGroup, BasePK deletedBy) {
2868        customerTypeContactListGroup.setThruTime(session.START_TIME_LONG);
2869        customerTypeContactListGroup.store();
2870
2871        sendEvent(customerTypeContactListGroup.getContactListGroupPK(), EventTypes.MODIFY, customerTypeContactListGroup.getPrimaryKey(), EventTypes.DELETE, deletedBy);
2872    }
2873
2874    public void deleteCustomerTypeContactListGroups(List<CustomerTypeContactListGroup> customerTypeContactListGroups, BasePK deletedBy) {
2875        customerTypeContactListGroups.forEach((customerTypeContactListGroup) -> 
2876                deleteCustomerTypeContactListGroup(customerTypeContactListGroup, deletedBy)
2877        );
2878    }
2879
2880    public void deleteCustomerTypeContactListGroupsByCustomerType(CustomerType customerType, BasePK deletedBy) {
2881        deleteCustomerTypeContactListGroups(getCustomerTypeContactListGroupsByCustomerTypeForUpdate(customerType), deletedBy);
2882    }
2883
2884    public void deleteCustomerTypeContactListGroupsByContactListGroup(ContactListGroup contactListGroup, BasePK deletedBy) {
2885        deleteCustomerTypeContactListGroups(getCustomerTypeContactListGroupsByContactListGroupForUpdate(contactListGroup), deletedBy);
2886    }
2887    
2888    // --------------------------------------------------------------------------------
2889    //   Customer Type Contact Lists
2890    // --------------------------------------------------------------------------------
2891
2892    public CustomerTypeContactList createCustomerTypeContactList(CustomerType customerType, ContactList contactList, Boolean addWhenCreated, BasePK createdBy) {
2893        CustomerTypeContactList customerTypeContactList = CustomerTypeContactListFactory.getInstance().create(session, customerType, contactList, addWhenCreated,
2894                session.START_TIME_LONG, Session.MAX_TIME_LONG);
2895
2896        sendEvent(contactList.getPrimaryKey(), EventTypes.MODIFY, customerTypeContactList.getPrimaryKey(), EventTypes.CREATE, createdBy);
2897
2898        return customerTypeContactList;
2899    }
2900
2901    private static final Map<EntityPermission, String> getCustomerTypeContactListQueries;
2902
2903    static {
2904        Map<EntityPermission, String> queryMap = new HashMap<>(2);
2905
2906        queryMap.put(EntityPermission.READ_ONLY,
2907                "SELECT _ALL_ "
2908                + "FROM customertypecontactlists "
2909                + "WHERE cutyclst_cuty_customertypeid = ? AND cutyclst_clst_contactlistid = ? AND cutyclst_thrutime = ?");
2910        queryMap.put(EntityPermission.READ_WRITE,
2911                "SELECT _ALL_ "
2912                + "FROM customertypecontactlists "
2913                + "WHERE cutyclst_cuty_customertypeid = ? AND cutyclst_clst_contactlistid = ? AND cutyclst_thrutime = ? "
2914                + "FOR UPDATE");
2915        getCustomerTypeContactListQueries = Collections.unmodifiableMap(queryMap);
2916    }
2917
2918    private CustomerTypeContactList getCustomerTypeContactList(CustomerType customerType, ContactList contactList, EntityPermission entityPermission) {
2919        return CustomerTypeContactListFactory.getInstance().getEntityFromQuery(entityPermission, getCustomerTypeContactListQueries,
2920                customerType, contactList, Session.MAX_TIME);
2921    }
2922
2923    public CustomerTypeContactList getCustomerTypeContactList(CustomerType customerType, ContactList contactList) {
2924        return getCustomerTypeContactList(customerType, contactList, EntityPermission.READ_ONLY);
2925    }
2926
2927    public CustomerTypeContactList getCustomerTypeContactListForUpdate(CustomerType customerType, ContactList contactList) {
2928        return getCustomerTypeContactList(customerType, contactList, EntityPermission.READ_WRITE);
2929    }
2930
2931    public CustomerTypeContactListValue getCustomerTypeContactListValue(CustomerTypeContactList customerTypeContactList) {
2932        return customerTypeContactList == null? null: customerTypeContactList.getCustomerTypeContactListValue().clone();
2933    }
2934
2935    public CustomerTypeContactListValue getCustomerTypeContactListValueForUpdate(CustomerType customerType, ContactList contactList) {
2936        return getCustomerTypeContactListValue(getCustomerTypeContactListForUpdate(customerType, contactList));
2937    }
2938
2939    private static final Map<EntityPermission, String> getCustomerTypeContactListsByCustomerTypeQueries;
2940
2941    static {
2942        Map<EntityPermission, String> queryMap = new HashMap<>(2);
2943
2944        queryMap.put(EntityPermission.READ_ONLY,
2945                "SELECT _ALL_ "
2946                + "FROM customertypecontactlists, contactlists, contactlistdetails "
2947                + "WHERE cutyclst_cuty_customertypeid = ? AND cutyclst_thrutime = ? "
2948                + "AND cutyclst_clst_contactlistid = clst_contactlistid AND clst_lastdetailid = clstdt_contactlistdetailid "
2949                + "ORDER BY clstdt_sortorder, clstdt_contactlistname");
2950        queryMap.put(EntityPermission.READ_WRITE,
2951                "SELECT _ALL_ "
2952                + "FROM customertypecontactlists "
2953                + "WHERE cutyclst_cuty_customertypeid = ? AND cutyclst_thrutime = ? "
2954                + "FOR UPDATE");
2955        getCustomerTypeContactListsByCustomerTypeQueries = Collections.unmodifiableMap(queryMap);
2956    }
2957
2958    private List<CustomerTypeContactList> getCustomerTypeContactListsByCustomerType(CustomerType customerType, EntityPermission entityPermission) {
2959        return CustomerTypeContactListFactory.getInstance().getEntitiesFromQuery(entityPermission, getCustomerTypeContactListsByCustomerTypeQueries,
2960                customerType, Session.MAX_TIME);
2961    }
2962
2963    public List<CustomerTypeContactList> getCustomerTypeContactListsByCustomerType(CustomerType customerType) {
2964        return getCustomerTypeContactListsByCustomerType(customerType, EntityPermission.READ_ONLY);
2965    }
2966
2967    public List<CustomerTypeContactList> getCustomerTypeContactListsByCustomerTypeForUpdate(CustomerType customerType) {
2968        return getCustomerTypeContactListsByCustomerType(customerType, EntityPermission.READ_WRITE);
2969    }
2970
2971    private static final Map<EntityPermission, String> getCustomerTypeContactListsByContactListQueries;
2972
2973    static {
2974        Map<EntityPermission, String> queryMap = new HashMap<>(2);
2975
2976        queryMap.put(EntityPermission.READ_ONLY,
2977                "SELECT _ALL_ "
2978                + "FROM customertypecontactlists, customertypes, customertypedetails "
2979                + "WHERE cutyclst_clst_contactlistid = ? AND cutyclst_thrutime = ? "
2980                + "AND cutyclst_cuty_customertypeid = cuty_customertypeid AND cuty_lastdetailid = cutydt_customertypedetailid "
2981                + "ORDER BY cutydt_sortorder, cutydt_customertypename");
2982        queryMap.put(EntityPermission.READ_WRITE,
2983                "SELECT _ALL_ "
2984                + "FROM customertypecontactlists "
2985                + "WHERE cutyclst_clst_contactlistid = ? AND cutyclst_thrutime = ? "
2986                + "FOR UPDATE");
2987        getCustomerTypeContactListsByContactListQueries = Collections.unmodifiableMap(queryMap);
2988    }
2989
2990    private List<CustomerTypeContactList> getCustomerTypeContactListsByContactList(ContactList contactList, EntityPermission entityPermission) {
2991        return CustomerTypeContactListFactory.getInstance().getEntitiesFromQuery(entityPermission, getCustomerTypeContactListsByContactListQueries,
2992                contactList, Session.MAX_TIME);
2993    }
2994
2995    public List<CustomerTypeContactList> getCustomerTypeContactListsByContactList(ContactList contactList) {
2996        return getCustomerTypeContactListsByContactList(contactList, EntityPermission.READ_ONLY);
2997    }
2998
2999    public List<CustomerTypeContactList> getCustomerTypeContactListsByContactListForUpdate(ContactList contactList) {
3000        return getCustomerTypeContactListsByContactList(contactList, EntityPermission.READ_WRITE);
3001    }
3002
3003    public List<CustomerTypeContactListTransfer> getCustomerTypeContactListTransfers(UserVisit userVisit, Collection<CustomerTypeContactList> customerTypeContactLists) {
3004        List<CustomerTypeContactListTransfer> customerTypeContactListTransfers = new ArrayList<>(customerTypeContactLists.size());
3005        CustomerTypeContactListTransferCache customerTypeContactListTransferCache = getContactListTransferCaches(userVisit).getCustomerTypeContactListTransferCache();
3006
3007        customerTypeContactLists.forEach((customerTypeContactList) ->
3008                customerTypeContactListTransfers.add(customerTypeContactListTransferCache.getCustomerTypeContactListTransfer(customerTypeContactList))
3009        );
3010
3011        return customerTypeContactListTransfers;
3012    }
3013
3014    public List<CustomerTypeContactListTransfer> getCustomerTypeContactListTransfersByCustomerType(UserVisit userVisit, CustomerType customerType) {
3015        return getCustomerTypeContactListTransfers(userVisit, getCustomerTypeContactListsByCustomerType(customerType));
3016    }
3017
3018    public List<CustomerTypeContactListTransfer> getCustomerTypeContactListTransfersByContactList(UserVisit userVisit, ContactList contactList) {
3019        return getCustomerTypeContactListTransfers(userVisit, getCustomerTypeContactListsByContactList(contactList));
3020    }
3021
3022    public CustomerTypeContactListTransfer getCustomerTypeContactListTransfer(UserVisit userVisit, CustomerTypeContactList customerTypeContactList) {
3023        return getContactListTransferCaches(userVisit).getCustomerTypeContactListTransferCache().getCustomerTypeContactListTransfer(customerTypeContactList);
3024    }
3025
3026    public void updateCustomerTypeContactListFromValue(CustomerTypeContactListValue customerTypeContactListValue, BasePK updatedBy) {
3027        if(customerTypeContactListValue.hasBeenModified()) {
3028            CustomerTypeContactList customerTypeContactList = CustomerTypeContactListFactory.getInstance().getEntityFromPK(EntityPermission.READ_WRITE,
3029                     customerTypeContactListValue.getPrimaryKey());
3030
3031            customerTypeContactList.setThruTime(session.START_TIME_LONG);
3032            customerTypeContactList.store();
3033
3034            CustomerTypePK customerTypePK = customerTypeContactList.getCustomerType().getPrimaryKey(); // Not Updated
3035            ContactListPK contactListPK = customerTypeContactList.getContactListPK(); // Not Updated
3036            Boolean addWhenCreated = customerTypeContactListValue.getAddWhenCreated();
3037
3038            customerTypeContactList = CustomerTypeContactListFactory.getInstance().create(customerTypePK, contactListPK, addWhenCreated, session.START_TIME_LONG,
3039                    Session.MAX_TIME_LONG);
3040
3041            sendEvent(contactListPK, EventTypes.MODIFY, customerTypeContactList.getPrimaryKey(), EventTypes.MODIFY, updatedBy);
3042        }
3043    }
3044
3045    public void deleteCustomerTypeContactList(CustomerTypeContactList customerTypeContactList, BasePK deletedBy) {
3046        customerTypeContactList.setThruTime(session.START_TIME_LONG);
3047        customerTypeContactList.store();
3048
3049        sendEvent(customerTypeContactList.getContactListPK(), EventTypes.MODIFY, customerTypeContactList.getPrimaryKey(), EventTypes.DELETE, deletedBy);
3050    }
3051
3052    public void deleteCustomerTypeContactLists(List<CustomerTypeContactList> customerTypeContactLists, BasePK deletedBy) {
3053        customerTypeContactLists.forEach((customerTypeContactList) -> 
3054                deleteCustomerTypeContactList(customerTypeContactList, deletedBy)
3055        );
3056    }
3057
3058    public void deleteCustomerTypeContactListsByCustomerType(CustomerType customerType, BasePK deletedBy) {
3059        deleteCustomerTypeContactLists(getCustomerTypeContactListsByCustomerTypeForUpdate(customerType), deletedBy);
3060    }
3061
3062    public void deleteCustomerTypeContactListsByContactList(ContactList contactList, BasePK deletedBy) {
3063        deleteCustomerTypeContactLists(getCustomerTypeContactListsByContactListForUpdate(contactList), deletedBy);
3064    }
3065
3066    // --------------------------------------------------------------------------------
3067    //   Contact List Contact Mechanism Purposes
3068    // --------------------------------------------------------------------------------
3069
3070    public ContactListContactMechanismPurpose createContactListContactMechanismPurpose(ContactList contactList, ContactMechanismPurpose contactMechanismPurpose, Boolean isDefault, Integer sortOrder, BasePK createdBy) {
3071        ContactListContactMechanismPurpose defaultContactListContactMechanismPurpose = getDefaultContactListContactMechanismPurpose(contactList);
3072        boolean defaultFound = defaultContactListContactMechanismPurpose != null;
3073
3074        if(defaultFound && isDefault) {
3075            ContactListContactMechanismPurposeDetailValue defaultContactListContactMechanismPurposeDetailValue = getDefaultContactListContactMechanismPurposeDetailValueForUpdate(contactList);
3076
3077            defaultContactListContactMechanismPurposeDetailValue.setIsDefault(Boolean.FALSE);
3078            updateContactListContactMechanismPurposeFromValue(defaultContactListContactMechanismPurposeDetailValue, false, createdBy);
3079        } else if(!defaultFound) {
3080            isDefault = Boolean.TRUE;
3081        }
3082
3083        ContactListContactMechanismPurpose contactListContactMechanismPurpose = ContactListContactMechanismPurposeFactory.getInstance().create();
3084        ContactListContactMechanismPurposeDetail contactListContactMechanismPurposeDetail = ContactListContactMechanismPurposeDetailFactory.getInstance().create(contactListContactMechanismPurpose, contactList, contactMechanismPurpose, isDefault,
3085                sortOrder, session.START_TIME_LONG, Session.MAX_TIME_LONG);
3086
3087        // Convert to R/W
3088        contactListContactMechanismPurpose = ContactListContactMechanismPurposeFactory.getInstance().getEntityFromPK(EntityPermission.READ_WRITE, contactListContactMechanismPurpose.getPrimaryKey());
3089        contactListContactMechanismPurpose.setActiveDetail(contactListContactMechanismPurposeDetail);
3090        contactListContactMechanismPurpose.setLastDetail(contactListContactMechanismPurposeDetail);
3091        contactListContactMechanismPurpose.store();
3092
3093        sendEvent(contactListContactMechanismPurpose.getPrimaryKey(), EventTypes.CREATE, null, null, createdBy);
3094
3095        return contactListContactMechanismPurpose;
3096    }
3097
3098    private static final Map<EntityPermission, String> getContactListContactMechanismPurposeQueries;
3099
3100    static {
3101        Map<EntityPermission, String> queryMap = new HashMap<>(2);
3102
3103        queryMap.put(EntityPermission.READ_ONLY,
3104                "SELECT _ALL_ "
3105                + "FROM contactlistcontactmechanismpurposes, contactlistcontactmechanismpurposedetails "
3106                + "WHERE clstcmpr_activedetailid = clstcmprdt_contactlistcontactmechanismpurposedetailid "
3107                + "AND clstcmprdt_clst_contactlistid = ? AND clstcmprdt_cmpr_contactmechanismpurposeid = ?");
3108        queryMap.put(EntityPermission.READ_WRITE,
3109                "SELECT _ALL_ "
3110                + "FROM contactlistcontactmechanismpurposes, contactlistcontactmechanismpurposedetails "
3111                + "WHERE clstcmpr_activedetailid = clstcmprdt_contactlistcontactmechanismpurposedetailid "
3112                + "AND clstcmprdt_clst_contactlistid = ? AND clstcmprdt_cmpr_contactmechanismpurposeid = ? "
3113                + "FOR UPDATE");
3114        getContactListContactMechanismPurposeQueries = Collections.unmodifiableMap(queryMap);
3115    }
3116
3117    private ContactListContactMechanismPurpose getContactListContactMechanismPurpose(ContactList contactList, ContactMechanismPurpose contactMechanismPurpose, EntityPermission entityPermission) {
3118        return ContactListContactMechanismPurposeFactory.getInstance().getEntityFromQuery(entityPermission, getContactListContactMechanismPurposeQueries,
3119                contactList, contactMechanismPurpose);
3120    }
3121
3122    public ContactListContactMechanismPurpose getContactListContactMechanismPurpose(ContactList contactList, ContactMechanismPurpose contactMechanismPurpose) {
3123        return getContactListContactMechanismPurpose(contactList, contactMechanismPurpose, EntityPermission.READ_ONLY);
3124    }
3125
3126    public ContactListContactMechanismPurpose getContactListContactMechanismPurposeForUpdate(ContactList contactList, ContactMechanismPurpose contactMechanismPurpose) {
3127        return getContactListContactMechanismPurpose(contactList, contactMechanismPurpose, EntityPermission.READ_WRITE);
3128    }
3129
3130    public ContactListContactMechanismPurposeDetailValue getContactListContactMechanismPurposeDetailValueForUpdate(ContactListContactMechanismPurpose contactListContactMechanismPurpose) {
3131        return contactListContactMechanismPurpose == null? null: contactListContactMechanismPurpose.getLastDetailForUpdate().getContactListContactMechanismPurposeDetailValue().clone();
3132    }
3133
3134    public ContactListContactMechanismPurposeDetailValue getContactListContactMechanismPurposeDetailValueForUpdate(ContactList contactList, ContactMechanismPurpose contactMechanismPurpose) {
3135        return getContactListContactMechanismPurposeDetailValueForUpdate(getContactListContactMechanismPurposeForUpdate(contactList, contactMechanismPurpose));
3136    }
3137
3138    private static final Map<EntityPermission, String> getDefaultContactListContactMechanismPurposeQueries;
3139
3140    static {
3141        Map<EntityPermission, String> queryMap = new HashMap<>(2);
3142
3143        queryMap.put(EntityPermission.READ_ONLY,
3144                "SELECT _ALL_ "
3145                + "FROM contactlistcontactmechanismpurposes, contactlistcontactmechanismpurposedetails "
3146                + "WHERE clstcmpr_activedetailid = clstcmprdt_contactlistcontactmechanismpurposedetailid "
3147                + "AND clstcmprdt_clst_contactlistid = ? AND clstcmprdt_isdefault = 1");
3148        queryMap.put(EntityPermission.READ_WRITE,
3149                "SELECT _ALL_ "
3150                + "FROM contactlistcontactmechanismpurposes, contactlistcontactmechanismpurposedetails "
3151                + "WHERE clstcmpr_activedetailid = clstcmprdt_contactlistcontactmechanismpurposedetailid "
3152                + "AND clstcmprdt_clst_contactlistid = ? AND clstcmprdt_isdefault = 1 "
3153                + "FOR UPDATE");
3154        getDefaultContactListContactMechanismPurposeQueries = Collections.unmodifiableMap(queryMap);
3155    }
3156
3157    private ContactListContactMechanismPurpose getDefaultContactListContactMechanismPurpose(ContactList contactList, EntityPermission entityPermission) {
3158        return ContactListContactMechanismPurposeFactory.getInstance().getEntityFromQuery(entityPermission, getDefaultContactListContactMechanismPurposeQueries,
3159                contactList);
3160    }
3161
3162    public ContactListContactMechanismPurpose getDefaultContactListContactMechanismPurpose(ContactList contactList) {
3163        return getDefaultContactListContactMechanismPurpose(contactList, EntityPermission.READ_ONLY);
3164    }
3165
3166    public ContactListContactMechanismPurpose getDefaultContactListContactMechanismPurposeForUpdate(ContactList contactList) {
3167        return getDefaultContactListContactMechanismPurpose(contactList, EntityPermission.READ_WRITE);
3168    }
3169
3170    public ContactListContactMechanismPurposeDetailValue getDefaultContactListContactMechanismPurposeDetailValueForUpdate(ContactList contactList) {
3171        return getDefaultContactListContactMechanismPurposeForUpdate(contactList).getLastDetailForUpdate().getContactListContactMechanismPurposeDetailValue().clone();
3172    }
3173
3174    private static final Map<EntityPermission, String> getContactListContactMechanismPurposesByContactListQueries;
3175
3176    static {
3177        Map<EntityPermission, String> queryMap = new HashMap<>(2);
3178
3179        queryMap.put(EntityPermission.READ_ONLY,
3180                "SELECT _ALL_ "
3181                + "FROM contactlistcontactmechanismpurposes, contactlistcontactmechanismpurposedetails, contactmechanismpurposes "
3182                + "WHERE clstcmpr_activedetailid = clstcmprdt_contactlistcontactmechanismpurposedetailid AND clstcmprdt_clst_contactlistid = ? "
3183                + "AND clstcmprdt_cmpr_contactmechanismpurposeid = cmpr_contactmechanismpurposeid "
3184                + "ORDER BY cmpr_sortorder, cmpr_contactmechanismpurposename "
3185                + "_LIMIT_");
3186        queryMap.put(EntityPermission.READ_WRITE,
3187                "SELECT _ALL_ "
3188                + "FROM contactlistcontactmechanismpurposes, contactlistcontactmechanismpurposedetails "
3189                + "WHERE clstcmpr_activedetailid = clstcmprdt_contactlistcontactmechanismpurposedetailid AND clstcmprdt_clst_contactlistid = ? "
3190                + "FOR UPDATE");
3191        getContactListContactMechanismPurposesByContactListQueries = Collections.unmodifiableMap(queryMap);
3192    }
3193
3194    private List<ContactListContactMechanismPurpose> getContactListContactMechanismPurposesByContactList(ContactList contactList, EntityPermission entityPermission) {
3195        return ContactListContactMechanismPurposeFactory.getInstance().getEntitiesFromQuery(entityPermission, getContactListContactMechanismPurposesByContactListQueries,
3196                contactList);
3197    }
3198
3199    public List<ContactListContactMechanismPurpose> getContactListContactMechanismPurposesByContactList(ContactList contactList) {
3200        return getContactListContactMechanismPurposesByContactList(contactList, EntityPermission.READ_ONLY);
3201    }
3202
3203    public List<ContactListContactMechanismPurpose> getContactListContactMechanismPurposesByContactListForUpdate(ContactList contactList) {
3204        return getContactListContactMechanismPurposesByContactList(contactList, EntityPermission.READ_WRITE);
3205    }
3206
3207    private static final Map<EntityPermission, String> getContactListContactMechanismPurposesByContactMechanismPurposeQueries;
3208
3209    static {
3210        Map<EntityPermission, String> queryMap = new HashMap<>(2);
3211
3212        queryMap.put(EntityPermission.READ_ONLY,
3213                "SELECT _ALL_ "
3214                + "FROM contactlistcontactmechanismpurposes, contactlistcontactmechanismpurposedetails, contactLists, contactlistdetails "
3215                + "WHERE clstcmpr_activedetailid = clstcmprdt_contactlistcontactmechanismpurposedetailid AND clstcmprdt_cmpr_contactmechanismpurposeid = ? "
3216                + "AND clstcmprdt_clst_contactlistid = clst_contactlistid AND clst_lastdetailid = clstdt_contactlistdetailid "
3217                + "ORDER BY clstdt_sortorder, clstdt_contactlistname "
3218                + "_LIMIT_");
3219        queryMap.put(EntityPermission.READ_WRITE,
3220                "SELECT _ALL_ "
3221                + "FROM contactlistcontactmechanismpurposes, contactlistcontactmechanismpurposedetails "
3222                + "WHERE clstcmpr_activedetailid = clstcmprdt_contactlistcontactmechanismpurposedetailid AND clstcmprdt_cmpr_contactmechanismpurposeid = ? "
3223                + "FOR UPDATE");
3224        getContactListContactMechanismPurposesByContactMechanismPurposeQueries = Collections.unmodifiableMap(queryMap);
3225    }
3226
3227    private List<ContactListContactMechanismPurpose> getContactListContactMechanismPurposesByContactMechanismPurpose(ContactMechanismPurpose contactMechanismPurpose, EntityPermission entityPermission) {
3228        return ContactListContactMechanismPurposeFactory.getInstance().getEntitiesFromQuery(entityPermission, getContactListContactMechanismPurposesByContactMechanismPurposeQueries,
3229                contactMechanismPurpose);
3230    }
3231
3232    public List<ContactListContactMechanismPurpose> getContactListContactMechanismPurposesByContactMechanismPurpose(ContactMechanismPurpose contactMechanismPurpose) {
3233        return getContactListContactMechanismPurposesByContactMechanismPurpose(contactMechanismPurpose, EntityPermission.READ_ONLY);
3234    }
3235
3236    public List<ContactListContactMechanismPurpose> getContactListContactMechanismPurposesByContactMechanismPurposeForUpdate(ContactMechanismPurpose contactMechanismPurpose) {
3237        return getContactListContactMechanismPurposesByContactMechanismPurpose(contactMechanismPurpose, EntityPermission.READ_WRITE);
3238    }
3239
3240   public ContactListContactMechanismPurposeTransfer getContactListContactMechanismPurposeTransfer(UserVisit userVisit, ContactListContactMechanismPurpose contactListContactMechanismPurpose) {
3241        return getContactListTransferCaches(userVisit).getContactListContactMechanismPurposeTransferCache().getContactListContactMechanismPurposeTransfer(contactListContactMechanismPurpose);
3242    }
3243
3244    public List<ContactListContactMechanismPurposeTransfer> getContactListContactMechanismPurposeTransfers(List<ContactListContactMechanismPurpose> contactListContactMechanismPurposes, UserVisit userVisit) {
3245        List<ContactListContactMechanismPurposeTransfer> contactListContactMechanismPurposeTransfers = new ArrayList<>(contactListContactMechanismPurposes.size());
3246        ContactListContactMechanismPurposeTransferCache contactListContactMechanismPurposeTransferCache = getContactListTransferCaches(userVisit).getContactListContactMechanismPurposeTransferCache();
3247
3248        contactListContactMechanismPurposes.forEach((contactListContactMechanismPurpose) ->
3249                contactListContactMechanismPurposeTransfers.add(contactListContactMechanismPurposeTransferCache.getContactListContactMechanismPurposeTransfer(contactListContactMechanismPurpose))
3250        );
3251
3252        return contactListContactMechanismPurposeTransfers;
3253    }
3254
3255    public List<ContactListContactMechanismPurposeTransfer> getContactListContactMechanismPurposeTransfersByContactList(UserVisit userVisit, ContactList contactList) {
3256        return getContactListContactMechanismPurposeTransfers(getContactListContactMechanismPurposesByContactList(contactList), userVisit);
3257    }
3258    
3259    public List<ContactListContactMechanismPurposeTransfer> getContactListContactMechanismPurposeTransfersByContactMechanismPurpose(UserVisit userVisit, ContactMechanismPurpose contactMechanismPurpose) {
3260        return getContactListContactMechanismPurposeTransfers(getContactListContactMechanismPurposesByContactMechanismPurpose(contactMechanismPurpose), userVisit);
3261    }
3262    
3263    public ContactListContactMechanismPurposeChoicesBean getContactListContactMechanismPurposeChoices(String defaultContactListContactMechanismPurposeChoice, Language language, boolean allowNullChoice,
3264            ContactList contactList) {
3265        var contactControl = Session.getModelController(ContactControl.class);
3266        List<ContactListContactMechanismPurpose> contactListContactMechanismPurposes = getContactListContactMechanismPurposesByContactList(contactList);
3267        var size = contactListContactMechanismPurposes.size();
3268        var labels = new ArrayList<String>(size);
3269        var values = new ArrayList<String>(size);
3270        String defaultValue = null;
3271
3272        if(allowNullChoice) {
3273            labels.add("");
3274            values.add("");
3275
3276            if(defaultContactListContactMechanismPurposeChoice == null) {
3277                defaultValue = "";
3278            }
3279        }
3280
3281        for(var contactListContactMechanismPurpose : contactListContactMechanismPurposes) {
3282            ContactListContactMechanismPurposeDetail contactListContactMechanismPurposeDetail = contactListContactMechanismPurpose.getLastDetail();
3283            ContactMechanismPurpose contactMechanismPurpose = contactListContactMechanismPurposeDetail.getContactMechanismPurpose();
3284
3285            var label = contactControl.getBestContactMechanismPurposeDescription(contactMechanismPurpose, language);
3286            var value = contactMechanismPurpose.getContactMechanismPurposeName();
3287
3288            labels.add(label == null? value: label);
3289            values.add(value);
3290
3291            var usingDefaultChoice = defaultContactListContactMechanismPurposeChoice != null && defaultContactListContactMechanismPurposeChoice.equals(value);
3292            if(usingDefaultChoice || (defaultValue == null && contactListContactMechanismPurposeDetail.getIsDefault())) {
3293                defaultValue = value;
3294            }
3295        }
3296
3297        return new ContactListContactMechanismPurposeChoicesBean(labels, values, defaultValue);
3298    }
3299
3300    private void updateContactListContactMechanismPurposeFromValue(ContactListContactMechanismPurposeDetailValue contactListContactMechanismPurposeDetailValue, boolean checkDefault, BasePK updatedBy) {
3301        if(contactListContactMechanismPurposeDetailValue.hasBeenModified()) {
3302            ContactListContactMechanismPurpose contactListContactMechanismPurpose = ContactListContactMechanismPurposeFactory.getInstance().getEntityFromPK(EntityPermission.READ_WRITE,
3303                     contactListContactMechanismPurposeDetailValue.getContactListContactMechanismPurposePK());
3304            ContactListContactMechanismPurposeDetail contactListContactMechanismPurposeDetail = contactListContactMechanismPurpose.getActiveDetailForUpdate();
3305
3306            contactListContactMechanismPurposeDetail.setThruTime(session.START_TIME_LONG);
3307            contactListContactMechanismPurposeDetail.store();
3308
3309            ContactListContactMechanismPurposePK contactListContactMechanismPurposePK = contactListContactMechanismPurposeDetail.getContactListContactMechanismPurposePK(); // Not updated
3310            ContactList contactList = contactListContactMechanismPurposeDetail.getContactList();
3311            ContactListPK contactListPK = contactList.getPrimaryKey(); // Not updated
3312            ContactMechanismPurposePK contactMechanismPurposePK = contactListContactMechanismPurposeDetail.getContactMechanismPurposePK(); // Not updated
3313            Boolean isDefault = contactListContactMechanismPurposeDetailValue.getIsDefault();
3314            Integer sortOrder = contactListContactMechanismPurposeDetailValue.getSortOrder();
3315
3316            if(checkDefault) {
3317                ContactListContactMechanismPurpose defaultContactListContactMechanismPurpose = getDefaultContactListContactMechanismPurpose(contactList);
3318                boolean defaultFound = defaultContactListContactMechanismPurpose != null && !defaultContactListContactMechanismPurpose.equals(contactListContactMechanismPurpose);
3319
3320                if(isDefault && defaultFound) {
3321                    // If I'm the default, and a default already existed...
3322                    ContactListContactMechanismPurposeDetailValue defaultContactListContactMechanismPurposeDetailValue = getDefaultContactListContactMechanismPurposeDetailValueForUpdate(contactList);
3323
3324                    defaultContactListContactMechanismPurposeDetailValue.setIsDefault(Boolean.FALSE);
3325                    updateContactListContactMechanismPurposeFromValue(defaultContactListContactMechanismPurposeDetailValue, false, updatedBy);
3326                } else if(!isDefault && !defaultFound) {
3327                    // If I'm not the default, and no other default exists...
3328                    isDefault = Boolean.TRUE;
3329                }
3330            }
3331
3332            contactListContactMechanismPurposeDetail = ContactListContactMechanismPurposeDetailFactory.getInstance().create(contactListContactMechanismPurposePK, contactListPK, contactMechanismPurposePK, isDefault, sortOrder,
3333                    session.START_TIME_LONG, Session.MAX_TIME_LONG);
3334
3335            contactListContactMechanismPurpose.setActiveDetail(contactListContactMechanismPurposeDetail);
3336            contactListContactMechanismPurpose.setLastDetail(contactListContactMechanismPurposeDetail);
3337
3338            sendEvent(contactListContactMechanismPurposePK, EventTypes.MODIFY, null, null, updatedBy);
3339        }
3340    }
3341
3342    public void updateContactListContactMechanismPurposeFromValue(ContactListContactMechanismPurposeDetailValue contactListContactMechanismPurposeDetailValue, BasePK updatedBy) {
3343        updateContactListContactMechanismPurposeFromValue(contactListContactMechanismPurposeDetailValue, true, updatedBy);
3344    }
3345
3346    private void deleteContactListContactMechanismPurpose(ContactListContactMechanismPurpose contactListContactMechanismPurpose, boolean checkDefault, BasePK deletedBy) {
3347        ContactListContactMechanismPurposeDetail contactListContactMechanismPurposeDetail = contactListContactMechanismPurpose.getLastDetailForUpdate();
3348        ContactList contactList = contactListContactMechanismPurposeDetail.getContactList();
3349
3350        clearContactListContactMechanismPurposeFromPartyContactLists(contactListContactMechanismPurpose, deletedBy);
3351        
3352        contactListContactMechanismPurposeDetail.setThruTime(session.START_TIME_LONG);
3353        contactListContactMechanismPurpose.setActiveDetail(null);
3354        contactListContactMechanismPurpose.store();
3355
3356        if(checkDefault) {
3357            // Check for default, and pick one if necessary
3358            ContactListContactMechanismPurpose defaultContactListContactMechanismPurpose = getDefaultContactListContactMechanismPurpose(contactList);
3359
3360            if(defaultContactListContactMechanismPurpose == null) {
3361                List<ContactListContactMechanismPurpose> contactListContactMechanismPurposes = getContactListContactMechanismPurposesByContactListForUpdate(contactList);
3362
3363                if(!contactListContactMechanismPurposes.isEmpty()) {
3364                    Iterator<ContactListContactMechanismPurpose> iter = contactListContactMechanismPurposes.iterator();
3365                    if(iter.hasNext()) {
3366                        defaultContactListContactMechanismPurpose = iter.next();
3367                    }
3368                    ContactListContactMechanismPurposeDetailValue contactListContactMechanismPurposeDetailValue = Objects.requireNonNull(defaultContactListContactMechanismPurpose).getLastDetailForUpdate().getContactListContactMechanismPurposeDetailValue().clone();
3369
3370                    contactListContactMechanismPurposeDetailValue.setIsDefault(Boolean.TRUE);
3371                    updateContactListContactMechanismPurposeFromValue(contactListContactMechanismPurposeDetailValue, false, deletedBy);
3372                }
3373            }
3374        }
3375
3376        sendEvent(contactListContactMechanismPurpose.getPrimaryKey(), EventTypes.DELETE, null, null, deletedBy);
3377    }
3378
3379    public void deleteContactListContactMechanismPurpose(ContactListContactMechanismPurpose contactListContactMechanismPurpose, BasePK deletedBy) {
3380        deleteContactListContactMechanismPurpose(contactListContactMechanismPurpose, true, deletedBy);
3381    }
3382
3383    private void deleteContactListContactMechanismPurposes(List<ContactListContactMechanismPurpose> contactListContactMechanismPurposes, boolean checkDefault, BasePK deletedBy) {
3384        contactListContactMechanismPurposes.forEach((contactListContactMechanismPurpose) -> deleteContactListContactMechanismPurpose(contactListContactMechanismPurpose, checkDefault, deletedBy));
3385    }
3386
3387    public void deleteContactListContactMechanismPurposes(List<ContactListContactMechanismPurpose> contactListContactMechanismPurposes, BasePK deletedBy) {
3388        deleteContactListContactMechanismPurposes(contactListContactMechanismPurposes, true, deletedBy);
3389    }
3390    
3391    public void deleteContactListContactMechanismPurposesByContactList(ContactList contactList, BasePK deletedBy) {
3392        deleteContactListContactMechanismPurposes(getContactListContactMechanismPurposesByContactListForUpdate(contactList), false, deletedBy);
3393    }
3394    
3395    public void deleteContactListContactMechanismPurposesByContactMechanismPurpose(ContactMechanismPurpose contactMechanismPurpose, BasePK deletedBy) {
3396        deleteContactListContactMechanismPurposes(getContactListContactMechanismPurposesByContactMechanismPurposeForUpdate(contactMechanismPurpose), deletedBy);
3397    }
3398    
3399}