---
title: Employee profile retrieval
summary: Loads one employee profile from the security principal, ADP, virtual-employee, and WCIS sources used by SAIF.Business.
status: draft
owner: SAIF
last_reviewed: 2026-07-30
library: SAIF.Business
reference_type: package
operation_id: OP-SB-01
trigger: Caller requests one employee by mail ID or employee ID.
---

# Employee profile retrieval

This operation builds a `clsEmployeeData` object for one person. The implementation prefers the current security principal when the caller supplies a mail ID, falls back to ADP or virtual-employee rows, and only uses the WCIS fallback when a user-based lookup still has no ADP match.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-SB-01 |
| **Trigger** | Caller invokes `GetDataByMailID`, `GetDataByEmployeeID`, or a lazy employee adjunct property. |
| **Inputs** | User ID, employee ID, bypass-security-principal flag, include-virtual flag |
| **Outputs** | Hydrated `clsEmployeeData` instance |
| **Primary components** | `clsEmployeeData.GetDataByMailID`, `clsEmployeeData.GetDataByEmployeeID`, `clsEmployeeData.Criteria.BeforeRetrieve`, `clsEmployeeData.Criteria.ProcessRequests` |
| **Entry point** | `Business\SAIF.Business\clsEmployeeData.vb` |

## Steps

1. The caller chooses the single-record factory that matches the available identifier, then creates criteria with either a user ID or an employee ID and optionally turns on virtual-employee support ([SQL-023](../sql/SQL-023-employee-retrieval-adp-virtual-variant.md), [VIRTUAL_EMPLOYEE](../database-tables.md#virtual-employee)).
2. `BeforeRetrieve` prepares up to three requests in priority order: a security-principal request when the caller passed a user ID and did not bypass principal lookup, an ADP request that targets `USER_ID` or `EMPLID`, and a WCIS request reserved for the user-ID fallback path ([SQL-023](../sql/SQL-023-employee-retrieval-adp-virtual-variant.md), [SQL-024](../sql/SQL-024-wcis-employee-fallback.md), [ADP_EMPLOYEE](../database-tables.md#adp-employee), [WCIS_EMPLOYEE](../database-tables.md#wcis-employee)).
3. When the security-principal request succeeds, the object is filled directly from `clsAccountMaintProxy.GetUserInfo`, including name, mail ID, phone, and department metadata, and the database requests are skipped.
   - If the principal lookup returns no full name, the code clears the provisional result and continues into the ADP/WCIS retrieval path.
4. The ADP request executes the single-employee SQL and optionally unions `VIRTUAL_EMPLOYEE` rows when the criteria allows virtual records ([SQL-023](../sql/SQL-023-employee-retrieval-adp-virtual-variant.md), [ADP_EMPLOYEE](../database-tables.md#adp-employee), [VIRTUAL_EMPLOYEE](../database-tables.md#virtual-employee)).
5. `ProcessRequests` reads the first ADP row, populates identity, phone, email, department, title, active flag, supervisor, and desk-location fields, and keeps the result as the authoritative employee profile ([SQL-023](../sql/SQL-023-employee-retrieval-adp-virtual-variant.md), [ADP_EMPLOYEE](../database-tables.md#adp-employee)).
6. If the ADP request returned no row and the original lookup came from a user ID, `ProcessRequests` executes the WCIS fallback SQL and fills the object from WCIS name fields plus a synthesized `@saif.com` email address ([SQL-024](../sql/SQL-024-wcis-employee-fallback.md), [WCIS_EMPLOYEE](../database-tables.md#wcis-employee)).
   - When the caller starts from an employee ID instead of a user ID, the WCIS branch is not attempted.
7. Lazy adjunct accessors use smaller follow-up lookups for details that are not always loaded with the base profile, including desk location and mobile phone ([SQL-025](../sql/SQL-025-employee-adjunct-lookups.md), [ADP_EMPLOYEE](../database-tables.md#adp-employee), [ADP_EMPLOYEE_PHONE_VIEW](../database-tables.md#adp-employee-phone-view)).
8. The resulting object is returned to the caller, with helper methods such as `Exists`, `CanLeaveMessage`, and `PhoneByType` operating only on the fields hydrated by the earlier branches.

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
    Start([Employee lookup request]) --> Build[Build employee criteria]
    Build --> Principal{User ID and principal lookup enabled?}
    Principal -->|Yes| PrincipalLoad[Try security-principal user info]
    Principal -->|No| ADP[Query ADP or virtual employee]
    PrincipalLoad --> Found{Principal row usable?}
    Found -->|Yes| Return1([Return employee])
    Found -->|No| ADP
    ADP --> ADPFound{ADP row found?}
    ADPFound -->|Yes| Return2([Return employee])
    ADPFound -->|No| WCIS{Lookup started from user ID?}
    WCIS -->|Yes| WCISLoad[Query WCIS fallback]
    WCIS -->|No| Empty([Return empty object])
    WCISLoad --> Return3([Return fallback employee])
```

## Failure and edge-case behavior

- User-ID lookups that miss both the security principal and ADP can still succeed through the WCIS fallback, but employee-ID lookups do not take that path.
- Virtual-employee rows are only included when the factory or property explicitly enables `includeVirtualEmployee`.
- Desk-location and mobile-phone accessors depend on follow-up SQL calls and return empty values when the adjunct rows are absent.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [SQL catalog](../sql/index.md)
- [Database tables](../database-tables.md)

## Sources
- `Business\SAIF.Business\clsEmployeeData.vb`
