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.control.user.contact.server.command;
018
019import com.echothree.control.user.contact.common.form.CreateContactTelephoneForm;
020import com.echothree.control.user.contact.common.result.ContactResultFactory;
021import com.echothree.model.control.contact.common.ContactMechanismTypes;
022import com.echothree.model.control.contact.common.workflow.TelephoneStatusConstants;
023import com.echothree.model.control.contact.server.control.ContactControl;
024import com.echothree.model.control.core.server.control.EntityInstanceControl;
025import com.echothree.model.control.geo.server.control.GeoControl;
026import com.echothree.model.control.party.common.PartyTypes;
027import com.echothree.model.control.party.server.control.PartyControl;
028import com.echothree.model.control.security.common.SecurityRoleGroups;
029import com.echothree.model.control.security.common.SecurityRoles;
030import com.echothree.model.control.sequence.common.SequenceTypes;
031import com.echothree.model.control.sequence.server.logic.SequenceGeneratorLogic;
032import com.echothree.model.control.workflow.server.control.WorkflowControl;
033import com.echothree.model.data.user.common.pk.UserVisitPK;
034import com.echothree.util.common.command.BaseResult;
035import com.echothree.util.common.command.SecurityResult;
036import com.echothree.util.common.message.ExecutionErrors;
037import com.echothree.util.common.persistence.BasePK;
038import com.echothree.util.common.string.StringUtils;
039import com.echothree.util.common.validation.FieldDefinition;
040import com.echothree.util.common.validation.FieldType;
041import com.echothree.util.server.control.BaseSimpleCommand;
042import com.echothree.util.server.control.CommandSecurityDefinition;
043import com.echothree.util.server.control.PartyTypeDefinition;
044import com.echothree.util.server.control.SecurityRoleDefinition;
045import com.echothree.util.server.persistence.Session;
046import java.util.Arrays;
047import java.util.Collections;
048import java.util.List;
049import java.util.Locale;
050import java.util.regex.Pattern;
051import javax.enterprise.context.RequestScoped;
052
053@RequestScoped
054public class CreateContactTelephoneCommand
055        extends BaseSimpleCommand<CreateContactTelephoneForm> {
056
057    private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION;
058    private final static List<FieldDefinition> FORM_FIELD_DEFINITIONS;
059
060    static {
061        COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(Collections.unmodifiableList(Arrays.asList(
062                new PartyTypeDefinition(PartyTypes.UTILITY.name(), null),
063                new PartyTypeDefinition(PartyTypes.CUSTOMER.name(), null),
064                new PartyTypeDefinition(PartyTypes.VENDOR.name(), null),
065                new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), Collections.unmodifiableList(Arrays.asList(
066                        new SecurityRoleDefinition(SecurityRoleGroups.ContactMechanism.name(), SecurityRoles.Create.name())
067                        )))
068                )));
069
070        FORM_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
071                new FieldDefinition("PartyName", FieldType.ENTITY_NAME, false, null, null),
072                new FieldDefinition("CountryName", FieldType.ENTITY_NAME, true, null, null),
073                new FieldDefinition("AreaCode", FieldType.STRING, false, 1L, 5L),
074                new FieldDefinition("TelephoneNumber", FieldType.STRING, true, 1L, 25L),
075                new FieldDefinition("TelephoneExtension", FieldType.NUMBERS, false, 1L, 10L),
076                new FieldDefinition("AllowSolicitation", FieldType.BOOLEAN, true, null, null),
077                new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L)
078                ));
079    }
080    
081    /** Creates a new instance of CreateContactTelephoneCommand */
082    public CreateContactTelephoneCommand() {
083        super(COMMAND_SECURITY_DEFINITION, FORM_FIELD_DEFINITIONS, false);
084    }
085
086    @Override
087    protected SecurityResult security() {
088        var securityResult = super.security();
089
090        return securityResult != null ? securityResult : selfOnly(form);
091    }
092
093    @Override
094    protected BaseResult execute() {
095        var result = ContactResultFactory.getCreateContactTelephoneResult();
096        var partyControl = Session.getModelController(PartyControl.class);
097        var partyName = form.getPartyName();
098        var party = partyName == null ? getParty() : partyControl.getPartyByName(partyName);
099        
100        if(party != null) {
101            var geoControl = Session.getModelController(GeoControl.class);
102            var countryName = form.getCountryName();
103            var countryAlias = StringUtils.getInstance().cleanStringToName(countryName).toUpperCase(Locale.getDefault());
104            var countryGeoCode = geoControl.getCountryByAlias(countryAlias);
105            
106            if(countryGeoCode != null) {
107                var geoCodeCountry = geoControl.getGeoCodeCountry(countryGeoCode);
108                var areaCode = form.getAreaCode();
109                
110                if(!geoCodeCountry.getAreaCodeRequired() || areaCode != null) {
111                    var areaCodePattern = geoCodeCountry.getAreaCodePattern();
112                    var pattern = areaCodePattern == null? null: Pattern.compile(areaCodePattern);
113                    
114                    if(pattern == null || pattern.matcher(areaCode).matches()) {
115                        var telephoneNumberPattern = geoCodeCountry.getTelephoneNumberPattern();
116                        var telephoneNumber = form.getTelephoneNumber();
117                        
118                        pattern = telephoneNumberPattern == null? null: Pattern.compile(telephoneNumberPattern);
119                        
120                        if(pattern == null || pattern.matcher(telephoneNumber).matches()) {
121                            var contactControl = Session.getModelController(ContactControl.class);
122                            var entityInstanceControl = Session.getModelController(EntityInstanceControl.class);
123                            var workflowControl = Session.getModelController(WorkflowControl.class);
124                            BasePK createdBy = getPartyPK();
125                            var telephoneExtension = form.getTelephoneExtension();
126                            var allowSolicitation = Boolean.valueOf(form.getAllowSolicitation());
127                            var description = form.getDescription();
128                            var contactMechanismName = SequenceGeneratorLogic.getInstance().getNextSequenceValue(null, SequenceTypes.CONTACT_MECHANISM.name());
129
130                            var contactMechanismType = contactControl.getContactMechanismTypeByName(ContactMechanismTypes.TELECOM_ADDRESS.name());
131                            var contactMechanism = contactControl.createContactMechanism(contactMechanismName,
132                                    contactMechanismType, allowSolicitation, createdBy);
133                            
134                            contactControl.createContactTelephone(contactMechanism, countryGeoCode, areaCode, telephoneNumber,
135                                    telephoneExtension, createdBy);
136                            
137                            contactControl.createPartyContactMechanism(party, contactMechanism, description, false, 1, createdBy);
138
139                            var entityInstance = entityInstanceControl.getEntityInstanceByBasePK(contactMechanism.getPrimaryKey());
140                            workflowControl.addEntityToWorkflowUsingNames(null, TelephoneStatusConstants.Workflow_TELEPHONE_STATUS,
141                                    TelephoneStatusConstants.WorkflowEntrance_NEW_TELEPHONE, entityInstance, null, null, createdBy);
142                            
143                            result.setContactMechanismName(contactMechanism.getLastDetail().getContactMechanismName());
144                            result.setEntityRef(contactMechanism.getPrimaryKey().getEntityRef());
145                        } else {
146                            addExecutionError(ExecutionErrors.InvalidTelephoneNumber.name(), telephoneNumber);
147                        }
148                    } else {
149                        addExecutionError(ExecutionErrors.InvalidAreaCode.name(), areaCode);
150                    }
151                } else {
152                    addExecutionError(ExecutionErrors.MissingAreaCode.name());
153                }
154            } else {
155                addExecutionError(ExecutionErrors.UnknownCountryName.name(), countryName);
156            }
157        } else {
158            addExecutionError(ExecutionErrors.UnknownPartyName.name(), partyName);
159        }
160        
161        return result;
162    }
163    
164}