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