Skip to content

Maintain provider location

clsProviderLocation is the anchor record for a provider's practice location: it stores the business/individual identity, contact numbers, approval and eligibility flags, and its ProviderLocationSeqNum is the foreign key used by nearly every other class in this library. Every successful save or delete also pushes a ContactDto to Contact Manager through clsContactApi.

Field Value
Operation ID OP-PRV-03
Trigger Caller calls NewProviderLocation/GetProviderLocation, edits properties, and calls Save() or Delete()
Inputs ProviderSeqNum, ProviderTypeCode, BusinessFlag, name fields, phone/fax/toll-free numbers, WebSiteAddress, PayeeName, EmailAddr, approval/primary/fraud/ineligibility/activity flags
Outputs Persisted PROVIDER_LOCATION row; Contact Manager ContactDto sync
Primary components clsProviderLocation.Create, BeforeInsert/BeforeUpdate/BeforeDelete, FillContactDto, clsContactApi.AddContact/UpdateContact/RemoveContact
Entry point Business\SAIF.Business.Provider\clsProviderLocation.vb

Steps

  1. Create a new location. Create() sets ProviderSeqNum from the criteria, assigns a new ProviderLocationSeqNum via GetNextSeqNum("PROVIDER_LOCATION_SEQ"), defaults ApprovedUser = "SYSTEM", and stamps the acting user.
  2. Name normalization on entity-type change. Setting BusinessFlag = "Y" clears FirstName/MiddleName/LastName; for BusinessFlag = "N", editing any of FirstName/MiddleName/LastName rebuilds BusinessName as "First Middle Last" with collapsed double spaces; the BusinessName and LastName setters also maintain uppercase shadow columns used for search.
  3. Validate before save.
  4. BR-003: HasDuplicatePrimaryLocation blocks a save when PrimaryLocationFlag = "Y" and another primary location already exists for the same provider.
  5. BR-004: MissingProviderType requires ProviderTypeCode.
  6. BR-005: MissingBusinessName requires BusinessName when BusinessFlag = "Y".
  7. BR-006: MissingLastName requires LastName when BusinessFlag = "N".
  8. ValidPhoneNumber, ValidTollFreePhoneNumber, ValidFax, ValidTollFreeFax: hard errors requiring at least 12 formatted characters when a value is present.
  9. CommonBusinessRules.IsValidEmailAddress validates EmailAddr when supplied.
  10. Insert. BeforeInsert writes provider type, business/individual identity, approval/primary/fraud/ineligibility/activity flags, phone/fax/toll-free numbers, WebSiteAddress, PayeeName, EmailAddr, and audit fields into PROVIDER_LOCATION (SQL-028).
  11. FillContactDto() builds ContactDto with companyName/firstName/lastName/isCompanyType, primaryPhone (digits only), fax, providerlocationSeqNumber, specialityType (via clsProviderUtility.GetSpecialityDescriptionByCode), providerNumber, and tin (via clsProviderUtility.GetTaxIdByProviderSeqNum).
  12. On a rows-affected value other than 1: add "Insert Failed".
  13. On success: MarkOld(), then call clsContactApi.AddContact(...).
    • clsContactApi.AddContact sends an HTTP insert to Provider API route provider/{providerlocationSeqNumber} with the ContactDto body.
    • On an API exception: serialize the DTO to JSON, log it via Logging.clsLogError.CreateError(...), and add an ApiInsertError — the database row remains committed; there is no compensating rollback.*
  14. Update. BeforeUpdate writes the same field set to PROVIDER_LOCATION (SQL-076) with concurrency check WHERE PROVIDER_LOCATION_SEQ_NUM = :ProviderLocationSeqNum AND UPDATE_NUM = :UpdateNum.
  15. On a rows-affected value other than 1: add the DB contention error.
  16. On success: increment m_ProviderLocationSeqNum locally, MarkOld(), then call clsContactApi.UpdateContact(...) (route provider/{providerlocationSeqNumber}, same DTO); API failures are logged and surfaced as ApiUpdateError without blocking the already-committed DB update.
  17. Delete. BeforeDelete deletes the PROVIDER_LOCATION row by ProviderLocationSeqNum (SQL-098); the delete statement does not include an UPDATE_NUM concurrency check.
  18. On a rows-affected value other than 1: add the DB contention error.
  19. On success: call clsContactApi.RemoveContact(...) (route provider/{providerlocationSeqNumber}/remove); API failures are logged and surfaced as ApiDeleteError.
  20. The delete path does not run any of the payment/audit/note usage checks that exist elsewhere in the codebase — a commented-out IsBeingUsed guard suggests protective checks against HasPayment (CL_FINANCIAL_TRANS), HasAudit (CBP_AUDITED_SERVICE), and HasNote (CBP_NOTE) were planned but are not active.*

Process flow

flowchart TD
    Start([Caller creates or edits location]) --> Rules{Validation rules pass?}
    Rules -->|No| Fail([Broken rules returned])
    Rules -->|Yes| Which{Save or Delete?}
    Which -->|Save/Insert| Insert[Insert PROVIDER_LOCATION]
    Which -->|Save/Update| Update[Update PROVIDER_LOCATION]
    Which -->|Delete| Delete[Delete PROVIDER_LOCATION,<br>no in-use check]
    Insert --> RowsIns{RowsAffected = 1?}
    Update --> RowsUpd{RowsAffected = 1?}
    Delete --> RowsDel{RowsAffected = 1?}
    RowsIns -->|No| InsErr([Insert Failed])
    RowsIns -->|Yes| ApiAdd[Call clsContactApi.AddContact]
    RowsUpd -->|No| Contention([DB contention error])
    RowsUpd -->|Yes| ApiUpd[Call clsContactApi.UpdateContact]
    RowsDel -->|No| Contention
    RowsDel -->|Yes| ApiDel[Call clsContactApi.RemoveContact]
    ApiAdd --> Done([Contact Manager synced;<br>API failures logged, not blocking])
    ApiUpd --> Done
    ApiDel --> Done

Failure and edge-case behavior

  • Deletion has no in-use protection against existing payments, audits, or notes, unlike the analogous relationship-in-use check on clsProviderRelationship.*
  • API synchronization failures (insert/update/delete) are logged and surfaced as error messages, but the underlying database change is never rolled back — the location can end up out of sync with Contact Manager.*
  • A rows-affected value other than 1 is treated uniformly as either an insert failure or DB contention error across insert, update, and delete.

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