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