Skip to content

Customer/contact combined search

clsCustomerContactSearch.SearchForCustomerContacts is the single entry point callers use to search across both contacts (PERSON) and customers (COMPANY) with one request. The request object itself enforces population and result-size rules, then the dispatcher runs the contact search first, reduces the remaining quota by however many contacts were found, and runs the customer search only if quota remains.

Field Value
Operation ID OP-CC-01
Trigger Caller constructs a clsCustomerContactSearch.SearchRequest, sets search criteria, and calls the shared function SearchForCustomerContacts(inDPI, inRequest)
Inputs SearchRequest: name/first/last name strings, reference ID, customer type, relationship type, search-format code, search type (Contact, Customer, CustomerContact), split ratio, result limit
Outputs SearchResult: merged list of ICustomerContact matches, the formatted search strings actually used, and an informational message when results were truncated or the request was invalid
Primary components clsCustomerContactSearch.SearchForCustomerContacts, clsCustomerContactSearch.SearchRequest, clsContactCollection.SearchForContacts, clsCustomerCollection.SearchForCustomers
Entry point Business\SAIF.Business.CustomerContact\clsCustomerContactSearch.vb

Steps

  1. Normalize the request. PrepForSearch() fills NameString from LastNameString/FirstNameString when no combined name was supplied (for Customer or CustomerContact search types) and calls CalcLimits() to compute the initial contact/customer quotas from ResultLimit and the configured split ratio.
  2. Validate the request (BR-001). IsValidRequest re-runs CalcLimits() and returns IsCustomerSearchable Or IsContactSearchable; each of those properties requires the relevant criteria strings to be non-blank for the current SearchType.
  3. If invalid: SearchForCustomerContacts skips both search paths and returns a SearchResult with the message "Invalid Search Request." and no rows.
  4. Enforce and split the result cap (BR-002). CalcLimits() clamps ResultLimit to the ResultMax constant (300) and, for a combined CustomerContact search, allocates _ContactLimit and _CustomerLimit from the configured split ratio (default 50/50, validated by ValidateSplitRatio which requires two numeric parts summing to 100).
  5. Search contacts, if applicable. When IsContactSearchable is true and SearchType is Contact or CustomerContact, clsContactCollection.SearchForContacts(inDPI, inRequest) runs against PERSON (optionally joined to COMPANY_PERSON for a relationship-type filter) using the formatted, wildcarded search strings built by BuildSearchString (SQL-031, PERSON, COMPANY_PERSON). Every returned contact is added to the merged result list.
  6. After the contact search: if the contact result count is less than the remaining ResultLimit, the limit is reduced by that count for the customer search; otherwise the limit is forced to 0 and the response message is set to "There are more results than can be returned."
  7. Search customers, if applicable and quota remains. When IsCustomerSearchable is true, ResultLimit > 0, and SearchType is Customer or CustomerContact, clsCustomerCollection.SearchForCustomers(inDPI, inRequest) runs against COMPANY (optionally joined to COMPANY_PERSON for a relationship-type filter) using the same formatted search-string pattern (SQL-037, COMPANY, COMPANY_PERSON). Every returned customer is appended to the merged result list.
  8. Build the search-string patterns. For each populated criterion (NameString, FirstNameString, LastNameString, ReferenceID), BuildSearchString applies the selected CustomerContactSearchFormat (contains-default, contains-specific consonant matching, contains-exact, starts-with, ends-with, and their "exactly" variants) to build the wildcarded (%) SQL comparison string used by the contact and customer search SQL.
  9. Return the merged result. SearchForCustomerContacts returns a SearchResult carrying the accumulated message, the formatted name/first-name/last-name strings actually applied, and the combined Results list.

Process flow

The following diagram visualizes the combined search dispatch and quota handling.

flowchart TD
    Start([Caller calls SearchForCustomerContacts]) --> Prep[PrepForSearch:<br>normalize NameString, CalcLimits]
    Prep --> Valid{IsValidRequest?}
    Valid -->|No| Invalid([Return: Invalid Search Request])
    Valid -->|Yes| ContactCheck{IsContactSearchable<br>and SearchType includes Contact?}
    ContactCheck -->|Yes| ContactSearch[SearchForContacts against PERSON]
    ContactSearch --> Reduce{Contact count < ResultLimit?}
    Reduce -->|Yes| ReduceLimit[ResultLimit -= contact count]
    Reduce -->|No| ZeroLimit[ResultLimit = 0;<br>set truncation message]
    ContactCheck -->|No| CustomerCheck
    ReduceLimit --> CustomerCheck{IsCustomerSearchable<br>and ResultLimit > 0<br>and SearchType includes Customer?}
    ZeroLimit --> CustomerCheck
    CustomerCheck -->|Yes| CustomerSearch[SearchForCustomers against COMPANY]
    CustomerCheck -->|No| Merge[Merge results]
    CustomerSearch --> Merge
    Merge --> Done([Return SearchResult])

Failure and edge-case behavior

  • An invalid request (no populated criteria for the selected SearchType) short-circuits both search paths entirely; no SQL executes (BR-001).
  • The 300-row cap and split ratio mean a contact-heavy result set can consume the entire quota before the customer search runs, which is reported to the caller through the truncation message rather than as an error (BR-002).
  • ValidateSplitRatio silently ignores a malformed SplitRatio value (non-numeric parts, or parts that do not sum to 100) and leaves the previous ratio in effect rather than raising an error.*
  • SearchType.Customer or SearchType.Contact disables the other path entirely regardless of which criteria are populated.

Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.

Sources

  • Business\SAIF.Business.CustomerContact\clsCustomerContactSearch.vb
  • Business\SAIF.Business.CustomerContact\Contact\clsContact.vb
  • Business\SAIF.Business.CustomerContact\Customer\clsCustomer.vb