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 public PartyTypeObject getPartyType(final DataFetchingEnvironment env) { 096 return PartySecurityUtils.getHasPartyTypeAccess(env) ? new PartyTypeObject(getPartyDetail().getPartyType()) : null; 097 } 098 099 @GraphQLField 100 @GraphQLDescription("preferred language") 101 public LanguageObject getPreferredLanguage(final DataFetchingEnvironment env) { 102 var preferredLanguage = getPartyDetail().getPreferredLanguage(); 103 104 return preferredLanguage != null && PartySecurityUtils.getHasLanguageAccess(env) ? new LanguageObject(preferredLanguage) : null; 105 } 106 107 @GraphQLField 108 @GraphQLDescription("preferred currency") 109 public CurrencyObject getPreferredCurrency(final DataFetchingEnvironment env) { 110 var preferredCurrency = getPartyDetail().getPreferredCurrency(); 111 112 return preferredCurrency != null && AccountingSecurityUtils.getHasCurrencyAccess(env) ? new CurrencyObject(preferredCurrency) : null; 113 } 114 115 @GraphQLField 116 @GraphQLDescription("preferred time zone") 117 public TimeZoneObject getPreferredTimeZone(final DataFetchingEnvironment env) { 118 var preferredTimeZone = getPartyDetail().getPreferredTimeZone(); 119 120 return preferredTimeZone != null && PartySecurityUtils.getHasTimeZoneAccess(env) ? new TimeZoneObject(preferredTimeZone) : null; 121 } 122 123 @GraphQLField 124 @GraphQLDescription("preferred date time format") 125 public DateTimeFormatObject getPreferredDateTimeFormat(final DataFetchingEnvironment env) { 126 var preferredDateTimeFormat = getPartyDetail().getPreferredDateTimeFormat(); 127 128 return preferredDateTimeFormat != null && PartySecurityUtils.getHasDateTimeFormatAccess(env) ? new DateTimeFormatObject(preferredDateTimeFormat) : null; 129 } 130 131 @GraphQLField 132 @GraphQLDescription("person") 133 public PersonObject getPerson(final DataFetchingEnvironment env) { 134 var partyControl = Session.getModelController(PartyControl.class); 135 var person = partyControl.getPerson(party); 136 137 return person == null ? null : new PersonObject(person); 138 } 139 140 @GraphQLField 141 @GraphQLDescription("party group") 142 public PartyGroupObject getPartyGroup(final DataFetchingEnvironment env) { 143 var partyControl = Session.getModelController(PartyControl.class); 144 var partyGroup = partyControl.getPartyGroup(party); 145 146 return partyGroup == null ? null : new PartyGroupObject(partyGroup); 147 } 148 149 @GraphQLField 150 @GraphQLDescription("description") 151 @GraphQLNonNull 152 public String getDescription(final DataFetchingEnvironment env) { 153 var partyControl = Session.getModelController(PartyControl.class); 154 var userControl = Session.getModelController(UserControl.class); 155 156 return partyControl.getBestPartyDescription(party, userControl.getPreferredLanguageFromUserVisit(BaseGraphQl.getUserVisit(env))); 157 } 158 159 @GraphQLField 160 @GraphQLDescription("party aliases") 161 @GraphQLNonNull 162 @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class) 163 public CountingPaginatedData<PartyAliasObject> getPartyAliases(final DataFetchingEnvironment env) { 164 if(PartySecurityUtils.getHasPartyAliasesAccess(env, party)) { 165 var partyControl = Session.getModelController(PartyControl.class); 166 var totalCount = partyControl.countPartyAliasesByParty(party); 167 168 try(var objectLimiter = new ObjectLimiter(env, PartyAliasConstants.COMPONENT_VENDOR_NAME, PartyAliasConstants.ENTITY_TYPE_NAME, totalCount)) { 169 var entities = partyControl.getPartyAliasesByParty(party); 170 var partyAliases = entities.stream().map(PartyAliasObject::new).collect(Collectors.toCollection(() -> new ArrayList<>(entities.size()))); 171 172 return new CountedObjects<>(objectLimiter, partyAliases); 173 } 174 } else { 175 return Connections.emptyConnection(); 176 } 177 } 178 179 @GraphQLField 180 @GraphQLDescription("party contact mechanisms") 181 @GraphQLNonNull 182 @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class) 183 public CountingPaginatedData<PartyContactMechanismObject> getPartyContactMechanisms(final DataFetchingEnvironment env) { 184// if(ContactSecurityUtils.getHasPartyContactMechanismsAccess(env, party)) { 185 var contactControl = Session.getModelController(ContactControl.class); 186 var totalCount = contactControl.countPartyContactMechanismsByParty(party); 187 188 try(var objectLimiter = new ObjectLimiter(env, PartyContactMechanismConstants.COMPONENT_VENDOR_NAME, PartyContactMechanismConstants.ENTITY_TYPE_NAME, totalCount)) { 189 var entities = contactControl.getPartyContactMechanismsByParty(party); 190 var partyContactMechanismes = entities.stream().map(PartyContactMechanismObject::new).collect(Collectors.toCollection(() -> new ArrayList<>(entities.size()))); 191 192 return new CountedObjects<>(objectLimiter, partyContactMechanismes); 193 } 194// } else { 195// return Connections.emptyConnection(); 196// } 197 } 198 199 @GraphQLField 200 @GraphQLDescription("party contact mechanism purpose") 201 public PartyContactMechanismPurposeObject getPartyContactMechanismPurpose(final DataFetchingEnvironment env, 202 @GraphQLName("contactMechanismPurposeName") @GraphQLNonNull final String contactMechanismPurposeName) { 203 var commandForm = ContactFormFactory.getGetContactMechanismPurposeForm(); 204 205 commandForm.setContactMechanismPurposeName(contactMechanismPurposeName); 206 207 var contactMechanismPurpose = CDI.current().select(GetContactMechanismPurposeCommand.class).get().getEntityForGraphQl(getUserVisitPK(env), commandForm); 208 if(contactMechanismPurpose != null) { 209 var contactControl = Session.getModelController(ContactControl.class); 210 var partyContactMechanismPurpose = contactControl.getDefaultPartyContactMechanismPurpose(party, contactMechanismPurpose); 211 212 return partyContactMechanismPurpose == null ? null : new PartyContactMechanismPurposeObject(partyContactMechanismPurpose); 213 } else { 214 return null; 215 } 216 } 217 218 @GraphQLField 219 @GraphQLDescription("subscriptions") 220 @GraphQLNonNull 221 @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class) 222 public CountingPaginatedData<SubscriptionObject> getSubscriptions(final DataFetchingEnvironment env) { 223 if(SubscriptionSecurityUtils.getHasSubscriptionsAccess(env)) { 224 var subscriptionControl = Session.getModelController(SubscriptionControl.class); 225 var totalCount = subscriptionControl.countSubscriptionsByParty(party); 226 227 try(var objectLimiter = new ObjectLimiter(env, SubscriptionConstants.COMPONENT_VENDOR_NAME, SubscriptionConstants.ENTITY_TYPE_NAME, totalCount)) { 228 var entities = subscriptionControl.getSubscriptionsByParty(party); 229 var subscriptions = entities.stream().map(SubscriptionObject::new).collect(Collectors.toCollection(() -> new ArrayList<>(entities.size()))); 230 231 return new CountedObjects<>(objectLimiter, subscriptions); 232 } 233 } else { 234 return Connections.emptyConnection(); 235 } 236 } 237 238 @GraphQLField 239 @GraphQLDescription("party contact lists") 240 @GraphQLNonNull 241 @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class) 242 public CountingPaginatedData<PartyContactListObject> getPartyContactLists(final DataFetchingEnvironment env) { 243 if(ContactListSecurityUtils.getHasPartyContactListsAccess(env)) { 244 var contactListControl = Session.getModelController(ContactListControl.class); 245 var totalCount = contactListControl.countPartyContactListsByParty(party); 246 247 try(var objectLimiter = new ObjectLimiter(env, PartyContactListConstants.COMPONENT_VENDOR_NAME, PartyContactListConstants.ENTITY_TYPE_NAME, totalCount)) { 248 var entities = contactListControl.getPartyContactListsByParty(party); 249 var partyContactLists = entities.stream().map(PartyContactListObject::new).collect(Collectors.toCollection(() -> new ArrayList<>(entities.size()))); 250 251 return new CountedObjects<>(objectLimiter, partyContactLists); 252 } 253 } else { 254 return Connections.emptyConnection(); 255 } 256 } 257 258 @GraphQLField 259 @GraphQLDescription("party inventory costing method") 260 public PartyInventoryCostingMethodObject getPartyInventoryCostingMethod(final DataFetchingEnvironment env) { 261 if(InventorySecurityUtils.getHasPartyInventoryCostingMethodAccess(env)) { 262 var inventoryCostingMethodControl = Session.getModelController(InventoryCostingMethodControl.class); 263 var partyInventoryCostingMethod = inventoryCostingMethodControl.getPartyInventoryCostingMethod(party); 264 265 return partyInventoryCostingMethod == null ? null : new PartyInventoryCostingMethodObject(partyInventoryCostingMethod); 266 } else { 267 return null; 268 } 269 } 270 271 @GraphQLField 272 @GraphQLDescription("party bucket") 273 @GraphQLNonNull 274 @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class) 275 public CountingPaginatedData<PartyBucketObject> getPartyBuckets(final DataFetchingEnvironment env) { 276 if(InventorySecurityUtils.getHasPartyBucketsAccess(env)) { 277 var contactListControl = Session.getModelController(BucketControl.class); 278 var totalCount = contactListControl.countPartyBucketsByParty(party); 279 280 try(var objectLimiter = new ObjectLimiter(env, PartyBucketConstants.COMPONENT_VENDOR_NAME, PartyBucketConstants.ENTITY_TYPE_NAME, totalCount)) { 281 var entities = contactListControl.getPartyBucketsByParty(party); 282 var partyBuckets = entities.stream().map(PartyBucketObject::new).collect(Collectors.toCollection(() -> new ArrayList<>(entities.size()))); 283 284 return new CountedObjects<>(objectLimiter, partyBuckets); 285 } 286 } else { 287 return Connections.emptyConnection(); 288 } 289 } 290 291}