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¶
- Normalize the request.
PrepForSearch()fillsNameStringfromLastNameString/FirstNameStringwhen no combined name was supplied (forCustomerorCustomerContactsearch types) and callsCalcLimits()to compute the initial contact/customer quotas fromResultLimitand the configured split ratio. - Validate the request (BR-001).
IsValidRequestre-runsCalcLimits()and returnsIsCustomerSearchable Or IsContactSearchable; each of those properties requires the relevant criteria strings to be non-blank for the currentSearchType. - If invalid:
SearchForCustomerContactsskips both search paths and returns aSearchResultwith the message"Invalid Search Request."and no rows. - Enforce and split the result cap (BR-002).
CalcLimits()clampsResultLimitto theResultMaxconstant (300) and, for a combinedCustomerContactsearch, allocates_ContactLimitand_CustomerLimitfrom the configured split ratio (default50/50, validated byValidateSplitRatiowhich requires two numeric parts summing to 100). - Search contacts, if applicable. When
IsContactSearchableis true andSearchTypeisContactorCustomerContact,clsContactCollection.SearchForContacts(inDPI, inRequest)runs againstPERSON(optionally joined toCOMPANY_PERSONfor a relationship-type filter) using the formatted, wildcarded search strings built byBuildSearchString(SQL-031, PERSON, COMPANY_PERSON). Every returned contact is added to the merged result list. - 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 to0and the response message is set to"There are more results than can be returned." - Search customers, if applicable and quota remains. When
IsCustomerSearchableis true,ResultLimit > 0, andSearchTypeisCustomerorCustomerContact,clsCustomerCollection.SearchForCustomers(inDPI, inRequest)runs againstCOMPANY(optionally joined toCOMPANY_PERSONfor 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. - Build the search-string patterns. For each populated criterion (
NameString,FirstNameString,LastNameString,ReferenceID),BuildSearchStringapplies the selectedCustomerContactSearchFormat(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. - Return the merged result.
SearchForCustomerContactsreturns aSearchResultcarrying the accumulated message, the formatted name/first-name/last-name strings actually applied, and the combinedResultslist.
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).
ValidateSplitRatiosilently ignores a malformedSplitRatiovalue (non-numeric parts, or parts that do not sum to 100) and leaves the previous ratio in effect rather than raising an error.*SearchType.CustomerorSearchType.Contactdisables 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.
Related documentation¶
Sources¶
Business\SAIF.Business.CustomerContact\clsCustomerContactSearch.vbBusiness\SAIF.Business.CustomerContact\Contact\clsContact.vbBusiness\SAIF.Business.CustomerContact\Customer\clsCustomer.vb