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