001// -------------------------------------------------------------------------------- 002// Copyright 2002-2026 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.party.server.graphql; 018 019import com.echothree.control.user.contact.common.form.ContactFormFactory; 020import com.echothree.control.user.contact.server.command.GetContactMechanismPurposeCommand; 021import com.echothree.model.control.accounting.server.graphql.AccountingSecurityUtils; 022import com.echothree.model.control.accounting.server.graphql.CurrencyObject; 023import com.echothree.model.control.contact.server.control.ContactControl; 024import com.echothree.model.control.contact.server.graphql.PartyContactMechanismObject; 025import com.echothree.model.control.contact.server.graphql.PartyContactMechanismPurposeObject; 026import com.echothree.model.control.contactlist.server.control.ContactListControl; 027import com.echothree.model.control.contactlist.server.graphql.ContactListSecurityUtils; 028import com.echothree.model.control.contactlist.server.graphql.PartyContactListObject; 029import com.echothree.model.control.graphql.server.graphql.BaseEntityInstanceObject; 030import com.echothree.model.control.graphql.server.graphql.count.Connections; 031import com.echothree.model.control.graphql.server.graphql.count.CountedObjects; 032import com.echothree.model.control.graphql.server.graphql.count.CountingDataConnectionFetcher; 033import com.echothree.model.control.graphql.server.graphql.count.CountingPaginatedData; 034import com.echothree.model.control.graphql.server.util.BaseGraphQl; 035import static com.echothree.model.control.graphql.server.util.BaseGraphQl.getUserVisitPK; 036import com.echothree.model.control.graphql.server.util.count.ObjectLimiter; 037import com.echothree.model.control.party.server.control.PartyControl; 038import com.echothree.model.control.subscription.server.control.SubscriptionControl; 039import com.echothree.model.control.subscription.server.graphql.SubscriptionObject; 040import com.echothree.model.control.subscription.server.graphql.SubscriptionSecurityUtils; 041import com.echothree.model.control.user.server.control.UserControl; 042import com.echothree.model.data.contact.common.PartyContactMechanismConstants; 043import com.echothree.model.data.contactlist.common.PartyContactListConstants; 044import com.echothree.model.data.party.common.PartyAliasConstants; 045import com.echothree.model.data.party.server.entity.Party; 046import com.echothree.model.data.party.server.entity.PartyDetail; 047import com.echothree.model.data.subscription.common.SubscriptionConstants; 048import com.echothree.util.server.persistence.Session; 049import graphql.annotations.annotationTypes.GraphQLDescription; 050import graphql.annotations.annotationTypes.GraphQLField; 051import graphql.annotations.annotationTypes.GraphQLName; 052import graphql.annotations.annotationTypes.GraphQLNonNull; 053import graphql.annotations.connection.GraphQLConnection; 054import graphql.schema.DataFetchingEnvironment; 055import java.util.ArrayList; 056import java.util.stream.Collectors; 057import javax.enterprise.inject.spi.CDI; 058 059public abstract class BasePartyObject 060 extends BaseEntityInstanceObject { 061 062 protected final Party party; // Always Present 063 064 protected BasePartyObject(Party party) { 065 super(party.getPrimaryKey()); 066 067 this.party = party; 068 } 069 070 private PartyDetail partyDetail; // Optional, use getPartyDetail() 071 072 protected PartyDetail getPartyDetail() { 073 if(partyDetail == null) { 074 partyDetail = party.getLastDetail(); 075 } 076 077 return partyDetail; 078 } 079 080 @GraphQLField 081 @GraphQLDescription("party name") 082 @GraphQLNonNull 083 public String getPartyName() { 084 return getPartyDetail().getPartyName(); 085 } 086 087 @GraphQLField 088 @GraphQLDescription("party type") 089 @GraphQLNonNull 090 public PartyTypeObject getPartyType(final DataFetchingEnvironment env) { 091 return PartySecurityUtils.getHasPartyTypeAccess(env) ? new PartyTypeObject(getPartyDetail().getPartyType()) : null; 092 } 093 094 @GraphQLField 095 @GraphQLDescription("preferred language") 096 public LanguageObject getPreferredLanguage(final DataFetchingEnvironment env) { 097 var preferredLanguage = getPartyDetail().getPreferredLanguage(); 098 099 return preferredLanguage != null && PartySecurityUtils.getHasLanguageAccess(env) ? new LanguageObject(preferredLanguage) : null; 100 } 101 102 @GraphQLField 103 @GraphQLDescription("preferred currency") 104 public CurrencyObject getPreferredCurrency(final DataFetchingEnvironment env) { 105 var preferredCurrency = getPartyDetail().getPreferredCurrency(); 106 107 return preferredCurrency != null && AccountingSecurityUtils.getHasCurrencyAccess(env) ? new CurrencyObject(preferredCurrency) : null; 108 } 109 110 @GraphQLField 111 @GraphQLDescription("preferred time zone") 112 public TimeZoneObject getPreferredTimeZone(final DataFetchingEnvironment env) { 113 var preferredTimeZone = getPartyDetail().getPreferredTimeZone(); 114 115 return preferredTimeZone != null && PartySecurityUtils.getHasTimeZoneAccess(env) ? new TimeZoneObject(preferredTimeZone) : null; 116 } 117 118 @GraphQLField 119 @GraphQLDescription("preferred date time format") 120 public DateTimeFormatObject getPreferredDateTimeFormat(final DataFetchingEnvironment env) { 121 var preferredDateTimeFormat = getPartyDetail().getPreferredDateTimeFormat(); 122 123 return preferredDateTimeFormat != null && PartySecurityUtils.getHasDateTimeFormatAccess(env) ? new DateTimeFormatObject(preferredDateTimeFormat) : null; 124 } 125 126 @GraphQLField 127 @GraphQLDescription("person") 128 public PersonObject getPerson(final DataFetchingEnvironment env) { 129 var partyControl = Session.getModelController(PartyControl.class); 130 var person = partyControl.getPerson(party); 131 132 return person == null ? null : new PersonObject(person); 133 } 134 135 @GraphQLField 136 @GraphQLDescription("party group") 137 public PartyGroupObject getPartyGroup(final DataFetchingEnvironment env) { 138 var partyControl = Session.getModelController(PartyControl.class); 139 var partyGroup = partyControl.getPartyGroup(party); 140 141 return partyGroup == null ? null : new PartyGroupObject(partyGroup); 142 } 143 144 @GraphQLField 145 @GraphQLDescription("description") 146 @GraphQLNonNull 147 public String getDescription(final DataFetchingEnvironment env) { 148 var partyControl = Session.getModelController(PartyControl.class); 149 var userControl = Session.getModelController(UserControl.class); 150 151 return partyControl.getBestPartyDescription(party, userControl.getPreferredLanguageFromUserVisit(BaseGraphQl.getUserVisit(env))); 152 } 153 154 @GraphQLField 155 @GraphQLDescription("party aliases") 156 @GraphQLNonNull 157 @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class) 158 public CountingPaginatedData<PartyAliasObject> getPartyAliases(final DataFetchingEnvironment env) { 159 if(PartySecurityUtils.getHasPartyAliasesAccess(env, party)) { 160 var partyControl = Session.getModelController(PartyControl.class); 161 var totalCount = partyControl.countPartyAliasesByParty(party); 162 163 try(var objectLimiter = new ObjectLimiter(env, PartyAliasConstants.COMPONENT_VENDOR_NAME, PartyAliasConstants.ENTITY_TYPE_NAME, totalCount)) { 164 var entities = partyControl.getPartyAliasesByParty(party); 165 var partyAliases = entities.stream().map(PartyAliasObject::new).collect(Collectors.toCollection(() -> new ArrayList<>(entities.size()))); 166 167 return new CountedObjects<>(objectLimiter, partyAliases); 168 } 169 } else { 170 return Connections.emptyConnection(); 171 } 172 } 173 174 @GraphQLField 175 @GraphQLDescription("party contact mechanisms") 176 @GraphQLNonNull 177 @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class) 178 public CountingPaginatedData<PartyContactMechanismObject> getPartyContactMechanisms(final DataFetchingEnvironment env) { 179// if(ContactSecurityUtils.getHasPartyContactMechanismsAccess(env, party)) { 180 var contactControl = Session.getModelController(ContactControl.class); 181 var totalCount = contactControl.countPartyContactMechanismsByParty(party); 182 183 try(var objectLimiter = new ObjectLimiter(env, PartyContactMechanismConstants.COMPONENT_VENDOR_NAME, PartyContactMechanismConstants.ENTITY_TYPE_NAME, totalCount)) { 184 var entities = contactControl.getPartyContactMechanismsByParty(party); 185 var partyContactMechanismes = entities.stream().map(PartyContactMechanismObject::new).collect(Collectors.toCollection(() -> new ArrayList<>(entities.size()))); 186 187 return new CountedObjects<>(objectLimiter, partyContactMechanismes); 188 } 189// } else { 190// return Connections.emptyConnection(); 191// } 192 } 193 194 @GraphQLField 195 @GraphQLDescription("party contact mechanism purpose") 196 public PartyContactMechanismPurposeObject getPartyContactMechanismPurpose(final DataFetchingEnvironment env, 197 @GraphQLName("contactMechanismPurposeName") @GraphQLNonNull final String contactMechanismPurposeName) { 198 var commandForm = ContactFormFactory.getGetContactMechanismPurposeForm(); 199 200 commandForm.setContactMechanismPurposeName(contactMechanismPurposeName); 201 202 var contactMechanismPurpose = CDI.current().select(GetContactMechanismPurposeCommand.class).get().getEntityForGraphQl(getUserVisitPK(env), commandForm); 203 if(contactMechanismPurpose != null) { 204 var contactControl = Session.getModelController(ContactControl.class); 205 var partyContactMechanismPurpose = contactControl.getDefaultPartyContactMechanismPurpose(party, contactMechanismPurpose); 206 207 return partyContactMechanismPurpose == null ? null : new PartyContactMechanismPurposeObject(partyContactMechanismPurpose); 208 } else { 209 return null; 210 } 211 } 212 213 @GraphQLField 214 @GraphQLDescription("subscriptions") 215 @GraphQLNonNull 216 @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class) 217 public CountingPaginatedData<SubscriptionObject> getSubscriptions(final DataFetchingEnvironment env) { 218 if(SubscriptionSecurityUtils.getHasSubscriptionsAccess(env)) { 219 var subscriptionControl = Session.getModelController(SubscriptionControl.class); 220 var totalCount = subscriptionControl.countSubscriptionsByParty(party); 221 222 try(var objectLimiter = new ObjectLimiter(env, SubscriptionConstants.COMPONENT_VENDOR_NAME, SubscriptionConstants.ENTITY_TYPE_NAME, totalCount)) { 223 var entities = subscriptionControl.getSubscriptionsByParty(party); 224 var subscriptions = entities.stream().map(SubscriptionObject::new).collect(Collectors.toCollection(() -> new ArrayList<>(entities.size()))); 225 226 return new CountedObjects<>(objectLimiter, subscriptions); 227 } 228 } else { 229 return Connections.emptyConnection(); 230 } 231 } 232 233 @GraphQLField 234 @GraphQLDescription("party contact lists") 235 @GraphQLNonNull 236 @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class) 237 public CountingPaginatedData<PartyContactListObject> getPartyContactLists(final DataFetchingEnvironment env) { 238 if(ContactListSecurityUtils.getHasPartyContactListsAccess(env)) { 239 var contactListControl = Session.getModelController(ContactListControl.class); 240 var totalCount = contactListControl.countPartyContactListsByParty(party); 241 242 try(var objectLimiter = new ObjectLimiter(env, PartyContactListConstants.COMPONENT_VENDOR_NAME, PartyContactListConstants.ENTITY_TYPE_NAME, totalCount)) { 243 var entities = contactListControl.getPartyContactListsByParty(party); 244 var partyContactLists = entities.stream().map(PartyContactListObject::new).collect(Collectors.toCollection(() -> new ArrayList<>(entities.size()))); 245 246 return new CountedObjects<>(objectLimiter, partyContactLists); 247 } 248 } else { 249 return Connections.emptyConnection(); 250 } 251 } 252 253}