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