Skip to content

Maintain provider contact

clsProviderContact maintains a named contact (phone/email) attached to a provider location. Unlike the identity, tax ID, MCO membership, and relationship classes, its own Save() path does not call the accompanying clsContactApi helper in this codebase — the API wrapper exists as a separate, caller-driven sync utility.

Field Value
Operation ID OP-PRV-05
Trigger Caller calls NewProviderContact/GetProviderContact, edits properties, and calls Save() or Delete()
Inputs ProviderLocationSeqNum, ProviderContactCode, Name, EmailAddress, PhoneNumber
Outputs Persisted PROVIDER_CONTACT row
Primary components clsProviderContact.Create, BeforeInsert/BeforeUpdate/BeforeDelete, ValidateContactType, ValidateEmailPhone, ValidatePhone
Entry point Business\SAIF.Business.Provider\clsProviderContact.vb

Steps

  1. Create. NewProviderContact(inDataportal, inProviderLocationSeqNum) constructs with RetrieveType.Location; Create() assigns ProviderLocationSeqNum and a new seq num via GetNextSeqNum("PROVIDER_CONTACT_SEQ").
  2. Retrieve single. BeforeRetrieve/AfterRetrieve read PROVIDER_CONTACT by PROVIDER_CONTACT_SEQ_NUM (SQL-045); Fill(...) runs only when a row is returned, otherwise the object is still marked old with empty fields.*
  3. Retrieve collection. GetContacts(inDPI, inProviderLocationSeqNum) runs a direct SqlHelper.ResultSetQuery filtered by PROVIDER_LOCATION_SEQ_NUM to load every contact for a location.
  4. Validate before save.
  5. BR-009: ValidateContactType requires a nonblank ProviderContactCode ("Error: Select a contact type."); ValidateEmailPhone requires at least one of EmailAddress or PhoneNumber ("Error: Either a phone # or an email address must be entered.").
  6. CommonBusinessRules.IsValidEmailAddress validates EmailAddress format when present.
  7. ValidatePhone: hard error if PhoneNumber is present and its trimmed formatted length is less than 12 characters ("Error: Invalid phone number.").
  8. A contact-name-required rule exists in source as a commented-out call and is not currently enforced.*
  9. Insert. BeforeInsert writes PROVIDER_CONTACT_SEQ_NUM, PROVIDER_LOCATION_SEQ_NUM, PROVIDER_CONTACT_CODE, NAME, EMAIL_ADDR, PHONE_NUM (formatted via the PhoneNumber getter), and audit fields to PROVIDER_CONTACT (SQL-021).
  10. On a rows-affected value other than 1: add "Insert Failed"; otherwise MarkOld().
  11. Update. BeforeUpdate writes the same fields to PROVIDER_CONTACT (SQL-069) with concurrency check WHERE PROVIDER_CONTACT_SEQ_NUM = :ProviderContactSeqNum AND UPDATE_NUM = :UpdateNum.
  12. On a rows-affected value other than 1: add the DB contention error; otherwise increment m_UpdateNum and MarkOld().
  13. Delete. BeforeDelete deletes the PROVIDER_CONTACT row by PROVIDER_CONTACT_SEQ_NUM (SQL-091).
  14. On a rows-affected value other than 1: add the DB contention error; otherwise MarkNew().
  15. Separate API sync utility. clsContactApi.AddContact/UpdateContact/RemoveContact is a standalone wrapper that sends a ContactDto to Provider API routes provider/{0} (insert/update) and provider/{0}/remove (delete) via DataApiAccessLayer.InsertObject/UpdateObject/DeleteObject. Because clsProviderContact.Save()/Delete() never invoke this class, Contact Manager synchronization for contact records — if it happens at all — is driven by a caller outside this file rather than embedded in the persistence pipeline.*

Process flow

flowchart TD
    Start([Caller edits contact]) --> TypeCheck{Contact type entered?}
    TypeCheck -->|No| Fail([Missing type or<br>communication path blocks save])
    TypeCheck -->|Yes| CommCheck{Phone or email present?}
    CommCheck -->|Neither| Fail
    CommCheck -->|At least one| PhoneCheck{Phone present and valid length?}
    PhoneCheck -->|No, too short| Fail
    PhoneCheck -->|Yes or blank| Persist[Insert/update/delete PROVIDER_CONTACT]
    Persist --> Rows{RowsAffected = 1?}
    Rows -->|No| Contention([Insert Failed / DB contention error])
    Rows -->|Yes| Done([Save complete;<br>no automatic Contact Manager sync])

Failure and edge-case behavior

  • Save()/Delete() do not call clsContactApi, so provider contacts are the one maintenance class in this library whose persistence path does not automatically synchronize to Contact Manager.*
  • Contact name is not a required field despite a commented-out rule suggesting it once was.*
  • Retrieving a nonexistent contact seq num returns an unpopulated object rather than an explicit not-found error.*

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.Provider\clsProviderContact.vb
  • Business\SAIF.Business.Provider\Api\clsContactApi.vb