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.control.user.party.server.command; 018 019import com.echothree.control.user.party.common.form.CreateVendorForm; 020import com.echothree.control.user.party.common.result.PartyResultFactory; 021import com.echothree.model.control.accounting.common.AccountingConstants; 022import com.echothree.model.control.accounting.server.control.AccountingControl; 023import com.echothree.model.control.cancellationpolicy.common.CancellationKinds; 024import com.echothree.model.control.cancellationpolicy.server.control.CancellationPolicyControl; 025import com.echothree.model.control.contact.common.ContactMechanismPurposes; 026import com.echothree.model.control.contact.server.logic.ContactEmailAddressLogic; 027import com.echothree.model.control.contactlist.server.logic.ContactListLogic; 028import com.echothree.model.control.core.server.control.EntityInstanceControl; 029import com.echothree.model.control.item.server.control.ItemControl; 030import com.echothree.model.control.party.common.PartyTypes; 031import com.echothree.model.control.party.server.control.PartyControl; 032import com.echothree.model.control.returnpolicy.common.ReturnKinds; 033import com.echothree.model.control.returnpolicy.server.control.ReturnPolicyControl; 034import com.echothree.model.control.security.common.SecurityRoleGroups; 035import com.echothree.model.control.security.common.SecurityRoles; 036import com.echothree.model.control.shipment.server.control.FreeOnBoardControl; 037import com.echothree.model.control.shipment.server.control.PartyFreeOnBoardControl; 038import com.echothree.model.control.term.server.control.TermControl; 039import com.echothree.model.control.vendor.common.workflow.VendorStatusConstants; 040import com.echothree.model.control.vendor.server.control.VendorControl; 041import com.echothree.model.control.vendor.server.logic.VendorLogic; 042import com.echothree.model.control.workflow.server.control.WorkflowControl; 043import com.echothree.model.data.accounting.server.entity.Currency; 044import com.echothree.model.data.cancellationpolicy.server.entity.CancellationPolicy; 045import com.echothree.model.data.returnpolicy.server.entity.ReturnPolicy; 046import com.echothree.model.data.user.common.pk.UserVisitPK; 047import com.echothree.util.common.command.BaseResult; 048import com.echothree.util.common.message.ExecutionErrors; 049import com.echothree.util.common.persistence.BasePK; 050import com.echothree.util.common.validation.FieldDefinition; 051import com.echothree.util.common.validation.FieldType; 052import com.echothree.util.server.control.BaseSimpleCommand; 053import com.echothree.util.server.control.CommandSecurityDefinition; 054import com.echothree.util.server.control.PartyTypeDefinition; 055import com.echothree.util.server.control.SecurityRoleDefinition; 056import com.echothree.util.server.persistence.EntityPermission; 057import com.echothree.util.server.persistence.Session; 058import java.util.List; 059import org.apache.commons.codec.language.Soundex; 060import javax.enterprise.context.Dependent; 061 062@Dependent 063public class CreateVendorCommand 064 extends BaseSimpleCommand<CreateVendorForm> { 065 066 private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION; 067 private final static List<FieldDefinition> FORM_FIELD_DEFINITIONS; 068 069 static { 070 COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(List.of( 071 new PartyTypeDefinition(PartyTypes.UTILITY.name(), null), 072 new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), List.of( 073 new SecurityRoleDefinition(SecurityRoleGroups.Vendor.name(), SecurityRoles.Create.name()) 074 )) 075 )); 076 077 FORM_FIELD_DEFINITIONS = List.of( 078 new FieldDefinition("VendorName", FieldType.ENTITY_NAME, false, null, null), 079 new FieldDefinition("VendorTypeName", FieldType.ENTITY_NAME, false, null, null), 080 new FieldDefinition("CancellationPolicyName", FieldType.ENTITY_NAME, false, null, null), 081 new FieldDefinition("ReturnPolicyName", FieldType.ENTITY_NAME, false, null, null), 082 new FieldDefinition("ApGlAccountName", FieldType.ENTITY_NAME, false, null, null), 083 new FieldDefinition("MinimumPurchaseOrderLines", FieldType.UNSIGNED_INTEGER, false, null, null), 084 new FieldDefinition("MaximumPurchaseOrderLines", FieldType.UNSIGNED_INTEGER, false, null, null), 085 new FieldDefinition("MinimumPurchaseOrderAmount:CurrencyIsoName,PreferredCurrencyIsoName", FieldType.UNSIGNED_COST_LINE, false, null, null), 086 new FieldDefinition("MaximumPurchaseOrderAmount:CurrencyIsoName,PreferredCurrencyIsoName", FieldType.UNSIGNED_COST_LINE, false, null, null), 087 new FieldDefinition("UseItemPurchasingCategories", FieldType.BOOLEAN, true, null, null), 088 new FieldDefinition("DefaultItemAliasTypeName", FieldType.ENTITY_NAME, false, null, null), 089 new FieldDefinition("PersonalTitleId", FieldType.ID, false, null, null), 090 new FieldDefinition("FirstName", FieldType.STRING, false, 1L, 20L), 091 new FieldDefinition("MiddleName", FieldType.STRING, false, 1L, 20L), 092 new FieldDefinition("LastName", FieldType.STRING, false, 1L, 20L), 093 new FieldDefinition("NameSuffixId", FieldType.ID, false, null, null), 094 new FieldDefinition("Name", FieldType.STRING, false, 1L, 60L), 095 new FieldDefinition("PreferredLanguageIsoName", FieldType.ENTITY_NAME, false, null, null), 096 new FieldDefinition("PreferredCurrencyIsoName", FieldType.ENTITY_NAME, false, null, null), 097 new FieldDefinition("PreferredJavaTimeZoneName", FieldType.STRING, false, null, null), 098 new FieldDefinition("PreferredDateTimeFormatName", FieldType.ENTITY_NAME, false, null, null), 099 new FieldDefinition("EmailAddress", FieldType.EMAIL_ADDRESS, false, null, null), 100 new FieldDefinition("AllowSolicitation", FieldType.BOOLEAN, true, null, null) 101 ); 102 } 103 104 /** Creates a new instance of CreateVendorCommand */ 105 public CreateVendorCommand() { 106 super(COMMAND_SECURITY_DEFINITION, FORM_FIELD_DEFINITIONS, false); 107 } 108 109 @Override 110 protected BaseResult execute() { 111 var result = PartyResultFactory.getCreateVendorResult(); 112 var vendorControl = Session.getModelController(VendorControl.class); 113 var vendorName = form.getVendorName(); 114 var vendor = vendorName == null ? null : vendorControl.getVendorByName(vendorName); 115 116 if(vendor == null) { 117 var vendorTypeName = form.getVendorTypeName(); 118 var vendorType = vendorTypeName == null ? vendorControl.getDefaultVendorType() : vendorControl.getVendorTypeByName(vendorTypeName); 119 120 if(vendorType != null) { 121 var cancellationPolicyName = form.getCancellationPolicyName(); 122 CancellationPolicy cancellationPolicy = null; 123 124 if(cancellationPolicyName != null) { 125 var cancellationPolicyControl = Session.getModelController(CancellationPolicyControl.class); 126 var returnKind = cancellationPolicyControl.getCancellationKindByName(CancellationKinds.VENDOR_CANCELLATION.name()); 127 128 cancellationPolicy = cancellationPolicyControl.getCancellationPolicyByName(returnKind, cancellationPolicyName); 129 } 130 131 if(cancellationPolicyName == null || cancellationPolicy != null) { 132 var returnPolicyName = form.getReturnPolicyName(); 133 ReturnPolicy returnPolicy = null; 134 135 if(returnPolicyName != null) { 136 var returnPolicyControl = Session.getModelController(ReturnPolicyControl.class); 137 var returnKind = returnPolicyControl.getReturnKindByName(ReturnKinds.VENDOR_RETURN.name()); 138 139 returnPolicy = returnPolicyControl.getReturnPolicyByName(returnKind, returnPolicyName); 140 } 141 142 if(returnPolicyName == null || returnPolicy != null) { 143 var accountingControl = Session.getModelController(AccountingControl.class); 144 var apGlAccountName = form.getApGlAccountName(); 145 var apGlAccount = apGlAccountName == null ? null : accountingControl.getGlAccountByName(apGlAccountName); 146 147 if(apGlAccountName == null || apGlAccount != null) { 148 var glAccountCategoryName = apGlAccount == null ? null 149 : apGlAccount.getLastDetail().getGlAccountCategory().getLastDetail().getGlAccountCategoryName(); 150 151 if(glAccountCategoryName == null || glAccountCategoryName.equals(AccountingConstants.GlAccountCategory_ACCOUNTS_PAYABLE)) { 152 var itemControl = Session.getModelController(ItemControl.class); 153 var defaultItemAliasTypeName = form.getDefaultItemAliasTypeName(); 154 var defaultItemAliasType = itemControl.getItemAliasTypeByName(defaultItemAliasTypeName); 155 156 if(defaultItemAliasTypeName == null || defaultItemAliasType != null) { 157 if(defaultItemAliasType == null || !defaultItemAliasType.getLastDetail().getAllowMultiple()) { 158 var partyControl = Session.getModelController(PartyControl.class); 159 var preferredLanguageIsoName = form.getPreferredLanguageIsoName(); 160 var preferredLanguage = preferredLanguageIsoName == null ? null : partyControl.getLanguageByIsoName(preferredLanguageIsoName); 161 162 if(preferredLanguageIsoName == null || (preferredLanguage != null)) { 163 var preferredJavaTimeZoneName = form.getPreferredJavaTimeZoneName(); 164 var preferredTimeZone = preferredJavaTimeZoneName == null ? null : partyControl.getTimeZoneByJavaName(preferredJavaTimeZoneName); 165 166 if(preferredJavaTimeZoneName == null || (preferredTimeZone != null)) { 167 var preferredDateTimeFormatName = form.getPreferredDateTimeFormatName(); 168 var preferredDateTimeFormat = preferredDateTimeFormatName == null ? null : partyControl.getDateTimeFormatByName(preferredDateTimeFormatName); 169 170 if(preferredDateTimeFormatName == null || (preferredDateTimeFormat != null)) { 171 var preferredCurrencyIsoName = form.getPreferredCurrencyIsoName(); 172 Currency preferredCurrency; 173 174 if(preferredCurrencyIsoName == null) { 175 preferredCurrency = null; 176 } else { 177 preferredCurrency = accountingControl.getCurrencyByIsoName(preferredCurrencyIsoName); 178 } 179 180 if(preferredCurrencyIsoName == null || (preferredCurrency != null)) { 181 var entityInstanceControl = Session.getModelController(EntityInstanceControl.class); 182 var freeOnBoardControl = Session.getModelController(FreeOnBoardControl.class); 183 var partyFreeOnBoardControl = Session.getModelController(PartyFreeOnBoardControl.class); 184 var termControl = Session.getModelController(TermControl.class); 185 var workflowControl = Session.getModelController(WorkflowControl.class); 186 var vendorTypeDetail = vendorType.getLastDetail(); 187 var soundex = new Soundex(); 188 var partyType = partyControl.getPartyTypeByName(PartyTypes.VENDOR.name()); 189 BasePK createdBy = getPartyPK(); 190 var personalTitleId = form.getPersonalTitleId(); 191 var personalTitle = personalTitleId == null ? null : partyControl.convertPersonalTitleIdToEntity(personalTitleId, EntityPermission.READ_ONLY); 192 var firstName = form.getFirstName(); 193 var middleName = form.getMiddleName(); 194 var lastName = form.getLastName(); 195 var nameSuffixId = form.getNameSuffixId(); 196 var nameSuffix = nameSuffixId == null ? null : partyControl.convertNameSuffixIdToEntity(nameSuffixId, EntityPermission.READ_ONLY); 197 var name = form.getName(); 198 var emailAddress = form.getEmailAddress(); 199 var allowSolicitation = Boolean.valueOf(form.getAllowSolicitation()); 200 var strMinimumPurchaseOrderLines = form.getMinimumPurchaseOrderLines(); 201 var minimumPurchaseOrderLines = strMinimumPurchaseOrderLines == null ? null : Integer.valueOf(strMinimumPurchaseOrderLines); 202 var strMaximumPurchaseOrderLines = form.getMaximumPurchaseOrderLines(); 203 var maximumPurchaseOrderLines = strMaximumPurchaseOrderLines == null ? null : Integer.valueOf(strMaximumPurchaseOrderLines); 204 var strMinimumPurchaseOrderAmount = form.getMinimumPurchaseOrderAmount(); 205 var minimumPurchaseOrderAmount = strMinimumPurchaseOrderAmount == null ? null : Long.valueOf(strMinimumPurchaseOrderAmount); 206 var strMaximumPurchaseOrderAmount = form.getMaximumPurchaseOrderAmount(); 207 var maximumPurchaseOrderAmount = strMaximumPurchaseOrderAmount == null ? null : Long.valueOf(strMaximumPurchaseOrderAmount); 208 var useItemPurchasingCategories = Boolean.valueOf(form.getUseItemPurchasingCategories()); 209 210 String firstNameSdx; 211 try { 212 firstNameSdx = firstName == null ? null : soundex.encode(firstName); 213 } catch(IllegalArgumentException iae) { 214 firstNameSdx = null; 215 } 216 217 String middleNameSdx; 218 try { 219 middleNameSdx = middleName == null ? null : soundex.encode(middleName); 220 } catch(IllegalArgumentException iae) { 221 middleNameSdx = null; 222 } 223 224 String lastNameSdx; 225 try { 226 lastNameSdx = lastName == null ? null : soundex.encode(lastName); 227 } catch(IllegalArgumentException iae) { 228 lastNameSdx = null; 229 } 230 231 var party = partyControl.createParty(null, partyType, preferredLanguage, preferredCurrency, 232 preferredTimeZone, preferredDateTimeFormat, createdBy); 233 234 if(createdBy == null) { 235 createdBy = party.getPrimaryKey(); 236 } 237 238 if(personalTitle != null || firstName != null || middleName != null || lastName != null || nameSuffix != null) { 239 partyControl.createPerson(party, personalTitle, firstName, firstNameSdx, middleName, middleNameSdx, 240 lastName, lastNameSdx, nameSuffix, createdBy); 241 } 242 243 if(name != null) { 244 partyControl.createPartyGroup(party, name, createdBy); 245 } 246 247 vendor = VendorLogic.getInstance().createVendor(this, party, vendorName, vendorType, minimumPurchaseOrderLines, 248 maximumPurchaseOrderLines, minimumPurchaseOrderAmount, maximumPurchaseOrderAmount, 249 useItemPurchasingCategories, defaultItemAliasType, cancellationPolicy, returnPolicy, apGlAccount, 250 vendorTypeDetail.getDefaultHoldUntilComplete(), vendorTypeDetail.getDefaultAllowBackorders(), 251 vendorTypeDetail.getDefaultAllowSubstitutions(), vendorTypeDetail.getDefaultAllowCombiningShipments(), 252 vendorTypeDetail.getDefaultRequireReference(), vendorTypeDetail.getDefaultAllowReferenceDuplicates(), 253 vendorTypeDetail.getDefaultReferenceValidationPattern(), null, null, createdBy); 254 255 if(emailAddress != null) { 256 ContactEmailAddressLogic.getInstance().createContactEmailAddress(party, 257 emailAddress, allowSolicitation, null, 258 ContactMechanismPurposes.PRIMARY_EMAIL.name(), createdBy); 259 } 260 261 termControl.createPartyTerm(party, termControl.getDefaultTerm(), null, createdBy); 262 263 partyFreeOnBoardControl.createPartyFreeOnBoard(party, freeOnBoardControl.getDefaultFreeOnBoard(), createdBy); 264 265 ContactListLogic.getInstance().setupInitialContactLists(this, party, createdBy); 266 267 var entityInstance = entityInstanceControl.getEntityInstanceByBasePK(party.getPrimaryKey()); 268 workflowControl.addEntityToWorkflowUsingNames(null, VendorStatusConstants.Workflow_VENDOR_STATUS, 269 VendorStatusConstants.WorkflowEntrance_NEW_ACTIVE, entityInstance, null, null, createdBy); 270 } else { 271 addExecutionError(ExecutionErrors.UnknownCurrencyIsoName.name(), preferredCurrencyIsoName); 272 } 273 } else { 274 addExecutionError(ExecutionErrors.UnknownDateTimeFormatName.name(), preferredDateTimeFormatName); 275 } 276 } else { 277 addExecutionError(ExecutionErrors.UnknownJavaTimeZoneName.name(), preferredJavaTimeZoneName); 278 } 279 } else { 280 addExecutionError(ExecutionErrors.UnknownLanguageIsoName.name(), preferredLanguageIsoName); 281 } 282 } else { 283 addExecutionError(ExecutionErrors.InvalidItemAliasType.name(), defaultItemAliasTypeName); 284 } 285 } else { 286 addExecutionError(ExecutionErrors.UnknownDefaultItemAliasTypeName.name(), defaultItemAliasTypeName); 287 } 288 } else { 289 addExecutionError(ExecutionErrors.InvalidGlAccountCategory.name(), glAccountCategoryName); 290 } 291 } else { 292 addExecutionError(ExecutionErrors.UnknownApGlAccountName.name(), apGlAccountName); 293 } 294 } else { 295 addExecutionError(ExecutionErrors.UnknownReturnPolicyName.name(), returnPolicyName); 296 } 297 } else { 298 addExecutionError(ExecutionErrors.UnknownCancellationPolicyName.name(), cancellationPolicyName); 299 } 300 } else { 301 if(vendorTypeName != null) { 302 addExecutionError(ExecutionErrors.UnknownVendorTypeName.name(), vendorTypeName); 303 } else { 304 addExecutionError(ExecutionErrors.UnknownDefaultVendorType.name()); 305 } 306 } 307 } else { 308 addExecutionError(ExecutionErrors.DuplicateVendorName.name(), vendorName); 309 } 310 311 if(vendor != null) { 312 var party = vendor.getParty(); 313 314 result.setEntityRef(party.getPrimaryKey().getEntityRef()); 315 result.setVendorName(vendor.getVendorName()); 316 result.setPartyName(party.getLastDetail().getPartyName()); 317 } 318 319 return result; 320 } 321 322}