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.search.server.command; 018 019import com.echothree.control.user.search.common.form.IdentifyForm; 020import com.echothree.control.user.search.common.result.SearchResultFactory; 021import com.echothree.model.control.core.common.CoreOptions; 022import com.echothree.model.control.core.common.CoreProperties; 023import com.echothree.model.control.core.common.transfer.ComponentVendorTransfer; 024import com.echothree.model.control.core.common.transfer.EntityInstanceTransfer; 025import com.echothree.model.control.core.common.transfer.EntityTypeTransfer; 026import com.echothree.model.control.core.server.control.EntityAliasControl; 027import com.echothree.model.control.core.server.control.EntityAttributeGroupControl; 028import com.echothree.model.control.core.server.control.EntityInstanceControl; 029import com.echothree.model.control.core.server.search.ComponentVendorSearchEvaluator; 030import com.echothree.model.control.core.server.search.EntityAliasTypeSearchEvaluator; 031import com.echothree.model.control.core.server.search.EntityAttributeGroupSearchEvaluator; 032import com.echothree.model.control.core.server.search.EntityAttributeSearchEvaluator; 033import com.echothree.model.control.core.server.search.EntityListItemSearchEvaluator; 034import com.echothree.model.control.core.server.search.EntityTypeSearchEvaluator; 035import com.echothree.model.control.customer.server.control.CustomerControl; 036import com.echothree.model.control.customer.server.search.CustomerSearchEvaluator; 037import com.echothree.model.control.employee.server.control.EmployeeControl; 038import com.echothree.model.control.employee.server.search.EmployeeSearchEvaluator; 039import com.echothree.model.control.item.server.control.ItemControl; 040import com.echothree.model.control.item.server.search.ItemSearchEvaluator; 041import com.echothree.model.control.party.server.control.PartyControl; 042import com.echothree.model.control.search.common.SearchKinds; 043import com.echothree.model.control.search.common.SearchTypes; 044import com.echothree.model.control.search.server.control.SearchControl; 045import com.echothree.model.control.search.server.logic.SearchLogic; 046import com.echothree.model.control.security.common.SecurityRoleGroups; 047import com.echothree.model.control.security.common.SecurityRoles; 048import com.echothree.model.control.vendor.server.control.VendorControl; 049import com.echothree.model.control.vendor.server.search.VendorSearchEvaluator; 050import com.echothree.model.control.warehouse.server.control.WarehouseControl; 051import com.echothree.model.control.warehouse.server.search.WarehouseSearchEvaluator; 052import com.echothree.model.data.party.server.entity.Party; 053import com.echothree.model.data.search.server.entity.SearchKind; 054import com.echothree.model.data.search.server.entity.SearchType; 055import com.echothree.model.data.user.server.entity.UserVisit; 056import com.echothree.util.common.command.BaseResult; 057import com.echothree.util.common.string.NameResult; 058import com.echothree.util.common.validation.FieldDefinition; 059import com.echothree.util.common.validation.FieldType; 060import com.echothree.util.server.control.BaseSimpleCommand; 061import com.echothree.util.server.message.DummyExecutionErrorAccumulator; 062import com.echothree.util.server.persistence.EntityNamesUtils; 063import com.echothree.util.server.persistence.translator.EntityInstanceAndNames; 064import com.echothree.util.server.string.NameCleaner; 065import com.echothree.util.server.validation.fieldtype.EntityNameFieldType; 066import java.util.HashSet; 067import java.util.List; 068import java.util.Set; 069import javax.enterprise.context.Dependent; 070import javax.inject.Inject; 071 072@Dependent 073public class IdentifyCommand 074 extends BaseSimpleCommand<IdentifyForm> { 075 076 private final static List<FieldDefinition> FORM_FIELD_DEFINITIONS; 077 078 static { 079 FORM_FIELD_DEFINITIONS = List.of( 080 new FieldDefinition("Target", FieldType.STRING, true, null, null) 081 ); 082 } 083 084 @Inject 085 CustomerControl customerControl; 086 087 @Inject 088 EmployeeControl employeeControl; 089 090 @Inject 091 EntityAliasControl entityAliasControl; 092 093 @Inject 094 protected EntityAttributeGroupControl entityAttributeGroupControl; 095 096 @Inject 097 EntityInstanceControl entityInstanceControl; 098 099 @Inject 100 ItemControl itemControl; 101 102 @Inject 103 PartyControl partyControl; 104 105 @Inject 106 SearchControl searchControl; 107 108 @Inject 109 VendorControl vendorControl; 110 111 @Inject 112 WarehouseControl warehouseControl; 113 114 @Inject 115 SearchLogic searchLogic; 116 117 118 /** Creates a new instance of IdentifyCommand */ 119 public IdentifyCommand() { 120 super(null, FORM_FIELD_DEFINITIONS, true); 121 } 122 123 @Override 124 protected void setupSession() { 125 super.setupSession(); 126 127 // Names are always included in the JumpResult, assembly of them is a little weird, so always disallow this option. 128 removeOption(CoreOptions.EntityInstanceIncludeNames); 129 130 // Ensure we're able to compare instances of and generate a HashCode for the EntityInstanceTransfers 131 removeFilteredTransferProperty(EntityInstanceTransfer.class, CoreProperties.ENTITY_TYPE); 132 removeFilteredTransferProperty(EntityTypeTransfer.class, CoreProperties.COMPONENT_VENDOR); 133 removeFilteredTransferProperty(EntityTypeTransfer.class, CoreProperties.ENTITY_TYPE_NAME); 134 removeFilteredTransferProperty(ComponentVendorTransfer.class, CoreProperties.COMPONENT_VENDOR_NAME); 135 } 136 137 private EntityInstanceTransfer fillInEntityInstance(EntityInstanceAndNames entityInstanceAndNames) { 138 var entityInstance = entityInstanceControl.getEntityInstanceTransfer(getUserVisit(), entityInstanceAndNames.getEntityInstance(), false, false, false, false); 139 140 entityInstance.setEntityNames(entityInstanceAndNames.getEntityNames()); 141 142 return entityInstance; 143 } 144 145 private void checkSequenceTypes(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 146 var entityInstanceAndNames = EntityNamesUtils.getInstance().getEntityNames(this, party, target, true); 147 148 if(entityInstanceAndNames != null) { 149 entityInstances.add(fillInEntityInstance(entityInstanceAndNames)); 150 } 151 } 152 153 private void checkItems(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 154 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 155 SecurityRoleGroups.Item.name(), SecurityRoles.Search.name())) { 156 var item = itemControl.getItemByNameThenAlias(target); 157 158 if(item != null) { 159 var entityInstance = entityInstanceControl.getEntityInstanceByBasePK(item.getPrimaryKey()); 160 var entityInstanceAndNames = EntityNamesUtils.getInstance().getEntityNames(entityInstance); 161 162 entityInstances.add(fillInEntityInstance(entityInstanceAndNames)); 163 } 164 } 165 } 166 167 private void checkCompanies(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 168 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 169 SecurityRoleGroups.Company.name(), SecurityRoles.Search.name())) { 170 var partyCompany = partyControl.getPartyCompanyByName(target); 171 172 if(partyCompany != null) { 173 var entityInstance = entityInstanceControl.getEntityInstanceByBasePK(partyCompany.getParty().getPrimaryKey()); 174 var entityInstanceAndNames = EntityNamesUtils.getInstance().getEntityNames(entityInstance); 175 176 entityInstances.add(fillInEntityInstance(entityInstanceAndNames)); 177 } 178 } 179 } 180 181 private void checkDivisions(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 182 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 183 SecurityRoleGroups.Division.name(), SecurityRoles.Search.name())) { 184 var partyDivisions = partyControl.getDivisionsByName(target); 185 186 partyDivisions.stream().map((partyDivision) -> entityInstanceControl.getEntityInstanceByBasePK(partyDivision.getParty().getPrimaryKey())).map((entityInstance) -> EntityNamesUtils.getInstance().getEntityNames(entityInstance)).forEach((entityInstanceAndNames) -> { 187 entityInstances.add(fillInEntityInstance(entityInstanceAndNames)); 188 }); 189 } 190 } 191 192 private void checkDepartments(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 193 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 194 SecurityRoleGroups.Department.name(), SecurityRoles.Search.name())) { 195 var partyDepartments = partyControl.getDepartmentsByName(target); 196 197 partyDepartments.stream().map((partyDepartment) -> entityInstanceControl.getEntityInstanceByBasePK(partyDepartment.getParty().getPrimaryKey())).map((entityInstance) -> EntityNamesUtils.getInstance().getEntityNames(entityInstance)).forEach((entityInstanceAndNames) -> { 198 entityInstances.add(fillInEntityInstance(entityInstanceAndNames)); 199 }); 200 } 201 } 202 203 private void checkWarehouses(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 204 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 205 SecurityRoleGroups.Warehouse.name(), SecurityRoles.Search.name())) { 206 var warehouse = warehouseControl.getWarehouseByName(target); 207 208 if(warehouse != null) { 209 var entityInstance = entityInstanceControl.getEntityInstanceByBasePK(warehouse.getParty().getPrimaryKey()); 210 var entityInstanceAndNames = EntityNamesUtils.getInstance().getEntityNames(entityInstance); 211 212 entityInstances.add(fillInEntityInstance(entityInstanceAndNames)); 213 } 214 } 215 } 216 217 private void checkLocations(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 218 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 219 SecurityRoleGroups.Location.name(), SecurityRoles.Search.name())) { 220 var locations = warehouseControl.getLocationsByName(target); 221 222 locations.stream().map((location) -> entityInstanceControl.getEntityInstanceByBasePK(location.getPrimaryKey())).map((entityInstance) -> EntityNamesUtils.getInstance().getEntityNames(entityInstance)).forEach((entityInstanceAndNames) -> { 223 entityInstances.add(fillInEntityInstance(entityInstanceAndNames)); 224 }); 225 } 226 } 227 228 private void checkEmployees(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 229 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 230 SecurityRoleGroups.Employee.name(), SecurityRoles.Search.name())) { 231 var partyEmployee = employeeControl.getPartyEmployeeByName(target); 232 233 if(partyEmployee != null) { 234 var entityInstance = entityInstanceControl.getEntityInstanceByBasePK(partyEmployee.getParty().getPrimaryKey()); 235 var entityInstanceAndNames = EntityNamesUtils.getInstance().getEntityNames(entityInstance); 236 237 entityInstances.add(fillInEntityInstance(entityInstanceAndNames)); 238 } 239 } 240 } 241 242 private void checkCustomers(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 243 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 244 SecurityRoleGroups.Customer.name(), SecurityRoles.Search.name())) { 245 var customer = customerControl.getCustomerByName(target); 246 247 if(customer != null) { 248 var entityInstance = entityInstanceControl.getEntityInstanceByBasePK(customer.getParty().getPrimaryKey()); 249 var entityInstanceAndNames = EntityNamesUtils.getInstance().getEntityNames(entityInstance); 250 251 entityInstances.add(fillInEntityInstance(entityInstanceAndNames)); 252 } 253 } 254 } 255 256 private void checkVendors(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 257 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 258 SecurityRoleGroups.Vendor.name(), SecurityRoles.Search.name())) { 259 var vendor = vendorControl.getVendorByName(target); 260 261 if(vendor != null) { 262 var entityInstance = entityInstanceControl.getEntityInstanceByBasePK(vendor.getParty().getPrimaryKey()); 263 var entityInstanceAndNames = EntityNamesUtils.getInstance().getEntityNames(entityInstance); 264 265 entityInstances.add(fillInEntityInstance(entityInstanceAndNames)); 266 } 267 } 268 } 269 270 private void checkVendorItems(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 271 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 272 SecurityRoleGroups.VendorItem.name(), SecurityRoles.Search.name())) { 273 var vendorItems = vendorControl.getVendorItemsByVendorItemName(target); 274 275 vendorItems.stream().map((vendorItem) -> entityInstanceControl.getEntityInstanceByBasePK(vendorItem.getPrimaryKey())).map((entityInstance) -> EntityNamesUtils.getInstance().getEntityNames(entityInstance)).forEach((entityInstanceAndNames) -> { 276 entityInstances.add(fillInEntityInstance(entityInstanceAndNames)); 277 }); 278 } 279 } 280 281 private void checkComponentVendors(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 282 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 283 SecurityRoleGroups.ComponentVendor.name(), SecurityRoles.Search.name())) { 284 var componentVendor = componentControl.getComponentVendorByName(target); 285 286 if(componentVendor != null) { 287 var entityInstance = entityInstanceControl.getEntityInstanceByBasePK(componentVendor.getPrimaryKey()); 288 var entityInstanceAndNames = EntityNamesUtils.getInstance().getEntityNames(entityInstance); 289 290 entityInstances.add(fillInEntityInstance(entityInstanceAndNames)); 291 } 292 } 293 } 294 295 private void checkEntityTypes(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 296 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 297 SecurityRoleGroups.EntityType.name(), SecurityRoles.Search.name())) { 298 var entityTypes = entityTypeControl.getEntityTypesByName(target); 299 300 entityTypes.stream().map((entityType) -> entityInstanceControl.getEntityInstanceByBasePK(entityType.getPrimaryKey())).map((entityInstance) -> EntityNamesUtils.getInstance().getEntityNames(entityInstance)).forEach((entityInstanceAndNames) -> { 301 entityInstances.add(fillInEntityInstance(entityInstanceAndNames)); 302 }); 303 } 304 } 305 306 private void checkEntityAliasTypes(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 307 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 308 SecurityRoleGroups.EntityAliasType.name(), SecurityRoles.Search.name())) { 309 var entityAliasTypes = entityAliasControl.getEntityAliasTypesByName(target); 310 311 entityAliasTypes.stream().map((entityAliasType) -> entityInstanceControl.getEntityInstanceByBasePK(entityAliasType.getPrimaryKey())).map((entityInstance) -> EntityNamesUtils.getInstance().getEntityNames(entityInstance)).forEach((entityInstanceAndNames) -> { 312 entityInstances.add(fillInEntityInstance(entityInstanceAndNames)); 313 }); 314 } 315 } 316 317 private void checkEntityAttributes(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 318 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 319 SecurityRoleGroups.EntityAttribute.name(), SecurityRoles.Search.name())) { 320 var entityAttributes = coreControl.getEntityAttributesByName(target); 321 322 entityAttributes.stream().map((entityAttribute) -> entityInstanceControl.getEntityInstanceByBasePK(entityAttribute.getPrimaryKey())).map((entityInstance) -> EntityNamesUtils.getInstance().getEntityNames(entityInstance)).forEach((entityInstanceAndNames) -> { 323 entityInstances.add(fillInEntityInstance(entityInstanceAndNames)); 324 }); 325 } 326 } 327 328 private void checkEntityListItems(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 329 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 330 SecurityRoleGroups.EntityListItem.name(), SecurityRoles.Search.name())) { 331 var entityListItems = coreControl.getEntityListItemsByName(target); 332 333 entityListItems.stream().map((entityListItem) -> entityInstanceControl.getEntityInstanceByBasePK(entityListItem.getPrimaryKey())).map((entityInstance) -> EntityNamesUtils.getInstance().getEntityNames(entityInstance)).forEach((entityInstanceAndNames) -> { 334 entityInstances.add(fillInEntityInstance(entityInstanceAndNames)); 335 }); 336 } 337 } 338 339 private void checkEntityAttributeGroups(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 340 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 341 SecurityRoleGroups.EntityAttributeGroup.name(), SecurityRoles.Search.name())) { 342 for(var entityAttributeGroup : entityAttributeGroupControl.getEntityAttributeGroupsByName(target)) { 343 var entityInstance = entityInstanceControl.getEntityInstanceByBasePK(entityAttributeGroup.getPrimaryKey()); 344 var entityInstanceAndNames = EntityNamesUtils.getInstance().getEntityNames(entityInstance); 345 346 entityInstances.add(fillInEntityInstance(entityInstanceAndNames)); 347 } 348 } 349 } 350 351 private void executeCustomerSearch(final UserVisit userVisit, final Set<EntityInstanceTransfer> entityInstances, 352 final SearchLogic searchLogic, final SearchKind searchKind, final SearchType searchType, 353 final String firstName, final String middleName, final String lastName, final String q) { 354 var customerSearchEvaluator = new CustomerSearchEvaluator(userVisit, searchType, 355 searchLogic.getDefaultSearchDefaultOperator(null), 356 searchLogic.getDefaultSearchSortOrder(null, searchKind), 357 searchLogic.getDefaultSearchSortDirection(null)); 358 359 customerSearchEvaluator.setFirstName(firstName); 360 customerSearchEvaluator.setFirstNameSoundex(false); 361 customerSearchEvaluator.setMiddleName(middleName); 362 customerSearchEvaluator.setMiddleNameSoundex(false); 363 customerSearchEvaluator.setLastName(lastName); 364 customerSearchEvaluator.setLastNameSoundex(false); 365 customerSearchEvaluator.setQ(null, q); 366 367 // Avoid using the real ExecutionErrorAccumulator in order to avoid either throwing an Exception or 368 // accumulating errors for this UC. 369 var dummyExecutionErrorAccumulator = new DummyExecutionErrorAccumulator(); 370 customerSearchEvaluator.execute(dummyExecutionErrorAccumulator); 371 372 if(!dummyExecutionErrorAccumulator.hasExecutionErrors()) { 373 addSearchResults(userVisit, searchType, entityInstances); 374 } 375 } 376 377 private void searchCustomers(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target, 378 final NameResult nameResult) { 379 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 380 SecurityRoleGroups.Customer.name(), SecurityRoles.Search.name())) { 381 var searchKind = searchLogic.getSearchKindByName(this, SearchKinds.CUSTOMER.name()); 382 383 if(!hasExecutionErrors()) { 384 var searchType = searchLogic.getSearchTypeByName(this, searchKind, SearchTypes.IDENTIFY.name()); 385 386 if(!hasExecutionErrors()) { 387 var userVisit = getUserVisit(); 388 389 // First attempt using a first and/or last name isolated from target. 390 executeCustomerSearch(userVisit, entityInstances, searchLogic, searchKind, searchType, 391 nameResult.getFirstName(), nameResult.getMiddleName(), nameResult.getLastName(), null); 392 // Then attempt searching for target using it as a query string. 393 executeCustomerSearch(userVisit, entityInstances, searchLogic, searchKind, searchType, 394 null, null, null, target); 395 } 396 } 397 } 398 } 399 400 private void executeEmployeeSearch(final UserVisit userVisit, final Set<EntityInstanceTransfer> entityInstances, 401 final SearchLogic searchLogic, final SearchKind searchKind, final SearchType searchType, 402 final String firstName, final String middleName, final String lastName, final String q) { 403 var employeeSearchEvaluator = new EmployeeSearchEvaluator(userVisit, searchType, 404 searchLogic.getDefaultSearchDefaultOperator(null), 405 searchLogic.getDefaultSearchSortOrder(null, searchKind), 406 searchLogic.getDefaultSearchSortDirection(null)); 407 408 employeeSearchEvaluator.setFirstName(firstName); 409 employeeSearchEvaluator.setFirstNameSoundex(false); 410 employeeSearchEvaluator.setMiddleName(middleName); 411 employeeSearchEvaluator.setMiddleNameSoundex(false); 412 employeeSearchEvaluator.setLastName(lastName); 413 employeeSearchEvaluator.setLastNameSoundex(false); 414 employeeSearchEvaluator.setQ(null, q); 415 416 // Avoid using the real ExecutionErrorAccumulator in order to avoid either throwing an Exception or 417 // accumulating errors for this UC. 418 var dummyExecutionErrorAccumulator = new DummyExecutionErrorAccumulator(); 419 employeeSearchEvaluator.execute(dummyExecutionErrorAccumulator); 420 421 if(!dummyExecutionErrorAccumulator.hasExecutionErrors()) { 422 addSearchResults(userVisit, searchType, entityInstances); 423 } 424 } 425 426 private void searchEmployees(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target, 427 final NameResult nameResult) { 428 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 429 SecurityRoleGroups.Employee.name(), SecurityRoles.Search.name())) { 430 var searchKind = searchLogic.getSearchKindByName(this, SearchKinds.EMPLOYEE.name()); 431 432 if(!hasExecutionErrors()) { 433 var searchType = searchLogic.getSearchTypeByName(this, searchKind, SearchTypes.IDENTIFY.name()); 434 435 if(!hasExecutionErrors()) { 436 var userVisit = getUserVisit(); 437 438 // First attempt using a first and/or last name isolated from target. 439 executeEmployeeSearch(userVisit, entityInstances, searchLogic, searchKind, searchType, 440 nameResult.getFirstName(), nameResult.getMiddleName(), nameResult.getLastName(), null); 441 // Then attempt searching for target using it as a query string. 442 executeEmployeeSearch(userVisit, entityInstances, searchLogic, searchKind, searchType, 443 null, null, null, target); 444 } 445 } 446 } 447 } 448 449 private void executeVendorSearch(final UserVisit userVisit, final Set<EntityInstanceTransfer> entityInstances, 450 final SearchLogic searchLogic, final SearchKind searchKind, final SearchType searchType, 451 final String firstName, final String middleName, final String lastName, final String q) { 452 var vendorSearchEvaluator = new VendorSearchEvaluator(userVisit, searchType, 453 searchLogic.getDefaultSearchDefaultOperator(null), 454 searchLogic.getDefaultSearchSortOrder(null, searchKind), 455 searchLogic.getDefaultSearchSortDirection(null)); 456 457 vendorSearchEvaluator.setFirstName(firstName); 458 vendorSearchEvaluator.setFirstNameSoundex(false); 459 vendorSearchEvaluator.setMiddleName(middleName); 460 vendorSearchEvaluator.setMiddleNameSoundex(false); 461 vendorSearchEvaluator.setLastName(lastName); 462 vendorSearchEvaluator.setLastNameSoundex(false); 463 vendorSearchEvaluator.setQ(null, q); 464 465 // Avoid using the real ExecutionErrorAccumulator in order to avoid either throwing an Exception or 466 // accumulating errors for this UC. 467 var dummyExecutionErrorAccumulator = new DummyExecutionErrorAccumulator(); 468 vendorSearchEvaluator.execute(dummyExecutionErrorAccumulator); 469 470 if(!dummyExecutionErrorAccumulator.hasExecutionErrors()) { 471 addSearchResults(userVisit, searchType, entityInstances); 472 } 473 } 474 475 private void searchVendors(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target, 476 final NameResult nameResult) { 477 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 478 SecurityRoleGroups.Vendor.name(), SecurityRoles.Search.name())) { 479 var searchKind = searchLogic.getSearchKindByName(this, SearchKinds.VENDOR.name()); 480 481 if(!hasExecutionErrors()) { 482 var searchType = searchLogic.getSearchTypeByName(this, searchKind, SearchTypes.IDENTIFY.name()); 483 484 if(!hasExecutionErrors()) { 485 var userVisit = getUserVisit(); 486 487 // First attempt using a first and/or last name isolated from target. 488 executeVendorSearch(userVisit, entityInstances, searchLogic, searchKind, searchType, 489 nameResult.getFirstName(), nameResult.getMiddleName(), nameResult.getLastName(), null); 490 // Then attempt searching for target using it as a query string. 491 executeVendorSearch(userVisit, entityInstances, searchLogic, searchKind, searchType, 492 null, null, null, target); 493 } 494 } 495 } 496 } 497 498 private void executeWarehouseSearch(final UserVisit userVisit, final Set<EntityInstanceTransfer> entityInstances, 499 final SearchLogic searchLogic, final SearchKind searchKind, final SearchType searchType, final String q) { 500 var warehouseSearchEvaluator = new WarehouseSearchEvaluator(userVisit, searchType, 501 searchLogic.getDefaultSearchDefaultOperator(null), 502 searchLogic.getDefaultSearchSortOrder(null, searchKind), 503 searchLogic.getDefaultSearchSortDirection(null)); 504 505 warehouseSearchEvaluator.setQ(null, q); 506 507 // Avoid using the real ExecutionErrorAccumulator in order to avoid either throwing an Exception or 508 // accumulating errors for this UC. 509 var dummyExecutionErrorAccumulator = new DummyExecutionErrorAccumulator(); 510 warehouseSearchEvaluator.execute(dummyExecutionErrorAccumulator); 511 512 if(!dummyExecutionErrorAccumulator.hasExecutionErrors()) { 513 addSearchResults(userVisit, searchType, entityInstances); 514 } 515 } 516 517 private void searchWarehouses(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 518 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 519 SecurityRoleGroups.Warehouse.name(), SecurityRoles.Search.name())) { 520 var searchKind = searchLogic.getSearchKindByName(this, SearchKinds.WAREHOUSE.name()); 521 522 if(!hasExecutionErrors()) { 523 var searchType = searchLogic.getSearchTypeByName(this, searchKind, SearchTypes.IDENTIFY.name()); 524 525 if(!hasExecutionErrors()) { 526 var userVisit = getUserVisit(); 527 528 // Attempt searching for target using it as a query string. 529 executeWarehouseSearch(userVisit, entityInstances, searchLogic, searchKind, searchType, 530 target); 531 } 532 } 533 } 534 } 535 536 private void executeItemSearch(final UserVisit userVisit, final Set<EntityInstanceTransfer> entityInstances, 537 final SearchLogic searchLogic, final SearchKind searchKind, final SearchType searchType, 538 final String q) { 539 var itemSearchEvaluator = new ItemSearchEvaluator(userVisit, null, searchType, 540 searchLogic.getDefaultSearchDefaultOperator(null), 541 searchLogic.getDefaultSearchSortOrder(null, searchKind), 542 searchLogic.getDefaultSearchSortDirection(null), 543 null); 544 545 itemSearchEvaluator.setQ(null, q); 546 547 // Avoid using the real ExecutionErrorAccumulator in order to avoid either throwing an Exception or 548 // accumulating errors for this UC. 549 var dummyExecutionErrorAccumulator = new DummyExecutionErrorAccumulator(); 550 itemSearchEvaluator.execute(dummyExecutionErrorAccumulator); 551 552 if(!dummyExecutionErrorAccumulator.hasExecutionErrors()) { 553 addSearchResults(userVisit, searchType, entityInstances); 554 } 555 } 556 557 private void searchItems(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 558 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 559 SecurityRoleGroups.Item.name(), SecurityRoles.Search.name())) { 560 var searchKind = searchLogic.getSearchKindByName(this, SearchKinds.ITEM.name()); 561 562 if(!hasExecutionErrors()) { 563 var searchType = searchLogic.getSearchTypeByName(this, searchKind, SearchTypes.IDENTIFY.name()); 564 565 if(!hasExecutionErrors()) { 566 var userVisit = getUserVisit(); 567 568 executeItemSearch(userVisit, entityInstances, searchLogic, searchKind, searchType, target); 569 } 570 } 571 } 572 } 573 574 private void executeComponentVendorSearch(final UserVisit userVisit, final Set<EntityInstanceTransfer> entityInstances, 575 final SearchLogic searchLogic, final SearchKind searchKind, final SearchType searchType, 576 final String q) { 577 var componentVendorSearchEvaluator = new ComponentVendorSearchEvaluator(userVisit, null, searchType, 578 searchLogic.getDefaultSearchDefaultOperator(null), 579 searchLogic.getDefaultSearchSortOrder(null, searchKind), 580 searchLogic.getDefaultSearchSortDirection(null), 581 null); 582 583 componentVendorSearchEvaluator.setQ(null, q); 584 585 // Avoid using the real ExecutionErrorAccumulator in order to avoid either throwing an Exception or 586 // accumulating errors for this UC. 587 var dummyExecutionErrorAccumulator = new DummyExecutionErrorAccumulator(); 588 componentVendorSearchEvaluator.execute(dummyExecutionErrorAccumulator); 589 590 if(!dummyExecutionErrorAccumulator.hasExecutionErrors()) { 591 addSearchResults(userVisit, searchType, entityInstances); 592 } 593 } 594 595 private void searchComponentVendors(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 596 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 597 SecurityRoleGroups.ComponentVendor.name(), SecurityRoles.Search.name())) { 598 var searchKind = searchLogic.getSearchKindByName(this, SearchKinds.COMPONENT_VENDOR.name()); 599 600 if(!hasExecutionErrors()) { 601 var searchType = searchLogic.getSearchTypeByName(this, searchKind, SearchTypes.IDENTIFY.name()); 602 603 if(!hasExecutionErrors()) { 604 var userVisit = getUserVisit(); 605 606 executeComponentVendorSearch(userVisit, entityInstances, searchLogic, searchKind, searchType, target); 607 } 608 } 609 } 610 } 611 612 private void executeEntityTypeSearch(final UserVisit userVisit, final Set<EntityInstanceTransfer> entityInstances, 613 final SearchLogic searchLogic, final SearchKind searchKind, final SearchType searchType, 614 final String q) { 615 var componentVendorSearchEvaluator = new EntityTypeSearchEvaluator(userVisit, null, searchType, 616 searchLogic.getDefaultSearchDefaultOperator(null), 617 searchLogic.getDefaultSearchSortOrder(null, searchKind), 618 searchLogic.getDefaultSearchSortDirection(null), 619 null); 620 621 componentVendorSearchEvaluator.setQ(null, q); 622 623 // Avoid using the real ExecutionErrorAccumulator in order to avoid either throwing an Exception or 624 // accumulating errors for this UC. 625 var dummyExecutionErrorAccumulator = new DummyExecutionErrorAccumulator(); 626 componentVendorSearchEvaluator.execute(dummyExecutionErrorAccumulator); 627 628 if(!dummyExecutionErrorAccumulator.hasExecutionErrors()) { 629 addSearchResults(userVisit, searchType, entityInstances); 630 } 631 } 632 633 private void searchEntityTypes(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 634 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 635 SecurityRoleGroups.EntityType.name(), SecurityRoles.Search.name())) { 636 var searchKind = searchLogic.getSearchKindByName(this, SearchKinds.ENTITY_TYPE.name()); 637 638 if(!hasExecutionErrors()) { 639 var searchType = searchLogic.getSearchTypeByName(this, searchKind, SearchTypes.IDENTIFY.name()); 640 641 if(!hasExecutionErrors()) { 642 var userVisit = getUserVisit(); 643 644 executeEntityTypeSearch(userVisit, entityInstances, searchLogic, searchKind, searchType, target); 645 } 646 } 647 } 648 } 649 650 private void executeEntityAliasTypeSearch(final UserVisit userVisit, final Set<EntityInstanceTransfer> entityInstances, 651 final SearchLogic searchLogic, final SearchKind searchKind, final SearchType searchType, 652 final String q) { 653 var componentVendorSearchEvaluator = new EntityAliasTypeSearchEvaluator(userVisit, null, searchType, 654 searchLogic.getDefaultSearchDefaultOperator(null), 655 searchLogic.getDefaultSearchSortOrder(null, searchKind), 656 searchLogic.getDefaultSearchSortDirection(null), 657 null); 658 659 componentVendorSearchEvaluator.setQ(null, q); 660 661 // Avoid using the real ExecutionErrorAccumulator in order to avoid either throwing an Exception or 662 // accumulating errors for this UC. 663 var dummyExecutionErrorAccumulator = new DummyExecutionErrorAccumulator(); 664 componentVendorSearchEvaluator.execute(dummyExecutionErrorAccumulator); 665 666 if(!dummyExecutionErrorAccumulator.hasExecutionErrors()) { 667 addSearchResults(userVisit, searchType, entityInstances); 668 } 669 } 670 671 private void searchEntityAliasTypes(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 672 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 673 SecurityRoleGroups.EntityAliasType.name(), SecurityRoles.Search.name())) { 674 var searchKind = searchLogic.getSearchKindByName(this, SearchKinds.ENTITY_TYPE.name()); 675 676 if(!hasExecutionErrors()) { 677 var searchType = searchLogic.getSearchTypeByName(this, searchKind, SearchTypes.IDENTIFY.name()); 678 679 if(!hasExecutionErrors()) { 680 var userVisit = getUserVisit(); 681 682 executeEntityAliasTypeSearch(userVisit, entityInstances, searchLogic, searchKind, searchType, target); 683 } 684 } 685 } 686 } 687 688 private void executeEntityAttributeSearch(final UserVisit userVisit, final Set<EntityInstanceTransfer> entityInstances, 689 final SearchLogic searchLogic, final SearchKind searchKind, final SearchType searchType, 690 final String q) { 691 var componentVendorSearchEvaluator = new EntityAttributeSearchEvaluator(userVisit, null, searchType, 692 searchLogic.getDefaultSearchDefaultOperator(null), 693 searchLogic.getDefaultSearchSortOrder(null, searchKind), 694 searchLogic.getDefaultSearchSortDirection(null), 695 null); 696 697 componentVendorSearchEvaluator.setQ(null, q); 698 699 // Avoid using the real ExecutionErrorAccumulator in order to avoid either throwing an Exception or 700 // accumulating errors for this UC. 701 var dummyExecutionErrorAccumulator = new DummyExecutionErrorAccumulator(); 702 componentVendorSearchEvaluator.execute(dummyExecutionErrorAccumulator); 703 704 if(!dummyExecutionErrorAccumulator.hasExecutionErrors()) { 705 addSearchResults(userVisit, searchType, entityInstances); 706 } 707 } 708 709 private void searchEntityAttributes(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 710 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 711 SecurityRoleGroups.EntityAttribute.name(), SecurityRoles.Search.name())) { 712 var searchKind = searchLogic.getSearchKindByName(this, SearchKinds.ENTITY_TYPE.name()); 713 714 if(!hasExecutionErrors()) { 715 var searchType = searchLogic.getSearchTypeByName(this, searchKind, SearchTypes.IDENTIFY.name()); 716 717 if(!hasExecutionErrors()) { 718 var userVisit = getUserVisit(); 719 720 executeEntityAttributeSearch(userVisit, entityInstances, searchLogic, searchKind, searchType, target); 721 } 722 } 723 } 724 } 725 726 private void executeEntityListItemSearch(final UserVisit userVisit, final Set<EntityInstanceTransfer> entityInstances, 727 final SearchLogic searchLogic, final SearchKind searchKind, final SearchType searchType, 728 final String q) { 729 var componentVendorSearchEvaluator = new EntityListItemSearchEvaluator(userVisit, null, searchType, 730 searchLogic.getDefaultSearchDefaultOperator(null), 731 searchLogic.getDefaultSearchSortOrder(null, searchKind), 732 searchLogic.getDefaultSearchSortDirection(null), 733 null); 734 735 componentVendorSearchEvaluator.setQ(null, q); 736 737 // Avoid using the real ExecutionErrorAccumulator in order to avoid either throwing an Exception or 738 // accumulating errors for this UC. 739 var dummyExecutionErrorAccumulator = new DummyExecutionErrorAccumulator(); 740 componentVendorSearchEvaluator.execute(dummyExecutionErrorAccumulator); 741 742 if(!dummyExecutionErrorAccumulator.hasExecutionErrors()) { 743 addSearchResults(userVisit, searchType, entityInstances); 744 } 745 } 746 747 private void searchEntityListItems(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 748 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 749 SecurityRoleGroups.EntityListItem.name(), SecurityRoles.Search.name())) { 750 var searchKind = searchLogic.getSearchKindByName(this, SearchKinds.ENTITY_TYPE.name()); 751 752 if(!hasExecutionErrors()) { 753 var searchType = searchLogic.getSearchTypeByName(this, searchKind, SearchTypes.IDENTIFY.name()); 754 755 if(!hasExecutionErrors()) { 756 var userVisit = getUserVisit(); 757 758 executeEntityListItemSearch(userVisit, entityInstances, searchLogic, searchKind, searchType, target); 759 } 760 } 761 } 762 } 763 764 private void executeEntityAttributeGroupSearch(final UserVisit userVisit, final Set<EntityInstanceTransfer> entityInstances, 765 final SearchLogic searchLogic, final SearchKind searchKind, final SearchType searchType, 766 final String q) { 767 var componentVendorSearchEvaluator = new EntityAttributeGroupSearchEvaluator(userVisit, null, searchType, 768 searchLogic.getDefaultSearchDefaultOperator(null), 769 searchLogic.getDefaultSearchSortOrder(null, searchKind), 770 searchLogic.getDefaultSearchSortDirection(null), 771 null); 772 773 componentVendorSearchEvaluator.setQ(null, q); 774 775 // Avoid using the real ExecutionErrorAccumulator in order to avoid either throwing an Exception or 776 // accumulating errors for this UC. 777 var dummyExecutionErrorAccumulator = new DummyExecutionErrorAccumulator(); 778 componentVendorSearchEvaluator.execute(dummyExecutionErrorAccumulator); 779 780 if(!dummyExecutionErrorAccumulator.hasExecutionErrors()) { 781 addSearchResults(userVisit, searchType, entityInstances); 782 } 783 } 784 785 private void searchEntityAttributeGroups(final Party party, final Set<EntityInstanceTransfer> entityInstances, final String target) { 786 if(securityRoleLogic.hasSecurityRoleUsingNames(this, party, 787 SecurityRoleGroups.EntityAttributeGroup.name(), SecurityRoles.Search.name())) { 788 var searchKind = searchLogic.getSearchKindByName(this, SearchKinds.ENTITY_TYPE.name()); 789 790 if(!hasExecutionErrors()) { 791 var searchType = searchLogic.getSearchTypeByName(this, searchKind, SearchTypes.IDENTIFY.name()); 792 793 if(!hasExecutionErrors()) { 794 var userVisit = getUserVisit(); 795 796 executeEntityAttributeGroupSearch(userVisit, entityInstances, searchLogic, searchKind, searchType, target); 797 } 798 } 799 } 800 } 801 802 // Add results from any of the BaseSearchEvaluators to the entityInstances. 803 private void addSearchResults(final UserVisit userVisit, final SearchType searchType, 804 final Set<EntityInstanceTransfer> entityInstances) { 805 var userVisitSearch = searchLogic.getUserVisitSearch(null, userVisit, searchType); 806 var resultEntityInstances = searchControl.getUserVisitSearchEntityInstances(userVisitSearch); 807 808 for(var resultEntityInstance : resultEntityInstances) { 809 var entityInstanceAndNames = EntityNamesUtils.getInstance().getEntityNames(resultEntityInstance); 810 811 entityInstances.add(fillInEntityInstance(entityInstanceAndNames)); 812 } 813 } 814 815 @Override 816 protected BaseResult execute() { 817 var result = SearchResultFactory.getIdentifyResult(); 818 var entityInstances = new HashSet<EntityInstanceTransfer>(); 819 var target = form.getTarget(); 820 var party = getParty(); 821 822 if(EntityNameFieldType.isValidName(target)) { 823 // Compile a list of all possible EntityInstances that the target may refer to. 824 checkSequenceTypes(party, entityInstances, target); // uses EEA 825 if(!hasExecutionErrors()) { 826 checkItems(party, entityInstances, target); // uses EEA 827 } 828 if(!hasExecutionErrors()) { 829 checkCompanies(party, entityInstances, target); // uses EEA 830 } 831 if(!hasExecutionErrors()) { 832 checkDivisions(party, entityInstances, target); // uses EEA 833 } 834 if(!hasExecutionErrors()) { 835 checkDepartments(party, entityInstances, target); // uses EEA 836 } 837 if(!hasExecutionErrors()) { 838 checkWarehouses(party, entityInstances, target); // uses EEA 839 } 840 if(!hasExecutionErrors()) { 841 checkLocations(party, entityInstances, target); // uses EEA 842 } 843 if(!hasExecutionErrors()) { 844 checkEmployees(party, entityInstances, target); // uses EEA 845 } 846 if(!hasExecutionErrors()) { 847 checkCustomers(party, entityInstances, target); // uses EEA 848 } 849 if(!hasExecutionErrors()) { 850 checkVendors(party, entityInstances, target); // uses EEA 851 } 852 if(!hasExecutionErrors()) { 853 checkVendorItems(party, entityInstances, target); // uses EEA 854 } 855 if(!hasExecutionErrors()) { 856 checkComponentVendors(party, entityInstances, target); // uses EEA 857 } 858 if(!hasExecutionErrors()) { 859 checkEntityTypes(party, entityInstances, target); // uses EEA 860 } 861 if(!hasExecutionErrors()) { 862 checkEntityAliasTypes(party, entityInstances, target); // uses EEA 863 } 864 if(!hasExecutionErrors()) { 865 checkEntityAttributes(party, entityInstances, target); // uses EEA 866 } 867 if(!hasExecutionErrors()) { 868 checkEntityListItems(party, entityInstances, target); // uses EEA 869 } 870 if(!hasExecutionErrors()) { 871 checkEntityAttributeGroups(party, entityInstances, target); // uses EEA 872 } 873 } 874 875 var nameResult = new NameCleaner().getCleansedName(target); 876 if(!hasExecutionErrors()) { 877 searchEmployees(party, entityInstances, target, nameResult); // uses EEA 878 } 879 if(!hasExecutionErrors()) { 880 searchCustomers(party, entityInstances, target, nameResult); // uses EEA 881 } 882 if(!hasExecutionErrors()) { 883 searchVendors(party, entityInstances, target, nameResult); // uses EEA 884 } 885 if(!hasExecutionErrors()) { 886 searchWarehouses(party, entityInstances, target); // uses EEA 887 } 888 if(!hasExecutionErrors()) { 889 searchItems(party, entityInstances, target); // uses EEA 890 } 891 if(!hasExecutionErrors()) { 892 searchComponentVendors(party, entityInstances, target); // uses EEA 893 } 894 if(!hasExecutionErrors()) { 895 searchEntityTypes(party, entityInstances, target); // uses EEA 896 } 897 if(!hasExecutionErrors()) { 898 searchEntityAliasTypes(party, entityInstances, target); // uses EEA 899 } 900 if(!hasExecutionErrors()) { 901 searchEntityAttributes(party, entityInstances, target); // uses EEA 902 } 903 if(!hasExecutionErrors()) { 904 searchEntityListItems(party, entityInstances, target); // uses EEA 905 } 906 if(!hasExecutionErrors()) { 907 searchEntityAttributeGroups(party, entityInstances, target); // uses EEA 908 } 909 910 result.setEntityInstances(entityInstances); 911 912 return result; 913 } 914 915}