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