Skip to content

Maintain provider tax ID and sync TIN contact

clsProviderTaxID maintains a provider's tax identification records, keyed by the raw 9-digit TaxID. Once saved, the TIN value itself is immutable — only its display formatting may change — and only the record flagged primary is synchronized to Contact Manager through clsTaxApi.UpdateTinContact.

Field Value
Operation ID OP-PRV-07
Trigger Caller calls NewProviderTaxID/GetProviderTaxID, edits properties, and calls Save() or Delete()
Inputs ProviderSeqNum, TaxID/TaxIDDisplayDescr, RegisteredName, EffDate/ExpDate, W9SentDate/W9ReceivedDate, Report1099Flag, address fields, ForeignAddressFlag, PrimaryTaxIDFlag
Outputs Persisted PROVIDER_TAX_ID row; ContactManager TaxDto sync for the primary TIN
Primary components clsProviderTaxID.Create, BeforeInsert/BeforeUpdate/BeforeDelete, FillTinContact, clsTaxApi.UpdateTinContact
Entry point Business\SAIF.Business.Provider\clsProviderTaxID.vb

Steps

  1. Create. Create() sets ProviderSeqNum from the criteria and defaults StateCode = "OR", CountryCode = "US".
  2. Retrieve. BeforeRetrieve joins PROVIDER_TAX_ID to PROVIDER on PROVIDER_SEQ_NUM, keyed by :TaxID (SQL-060). PrimaryTaxIDFlag is derived in SQL with DECODE(PROVIDER.PRIMARY_TAX_ID, PROVIDER_TAX_ID.TAX_ID, 'Y', 'N') rather than stored directly on the row. Fill() also stores m_RetrievedTaxID for the immutability check.
  3. Validate before save.
  4. MissingTIN/BR-011: ValidTIN requires a numeric value at least 9 digits long; ValidTINFormat requires the formatted display to match 00-0000000 (EIN) or 000-00-0000 (SSN) exactly.
  5. BR-025: AlteredTIN blocks changing the digits of an existing TIN (m_RetrievedTaxID differs from the current value); only the display format may change.
  6. IsDuplicateTIN: hard error querying PROVIDER_TAX_ID for an existing row with the same TAX_ID (BR-011).
  7. MissingRegisteredName: hard error requiring RegisteredName.
  8. ValidSentReceiptDate: hard error if W9ReceivedDate precedes W9SentDate; UnreasonableW9SentDate: hard error if the sent date is before 01/01/1850.
  9. BR-012: HasDuplicatePrimaryTaxID blocks a save when PrimaryTaxIDFlag = "Y" and another primary TIN already exists for the provider.
  10. ValidStatecode: hard error validating StateCode against the STATE reference table; ValidZipCodeExt: hard error requiring a numeric ZIP+4 when present.
  11. ValidateCleanAddress (warning only): runs the same USPS cleansing service directly, ignoring USPS error code "10"; any remaining error surfaces "Warning: Address may not be valid." without blocking the save.
  12. Foreign/domestic address side effects. Setting ForeignAddressFlag = "Y" clears city/state/country/ZIP/ZIP+4; switching back to domestic clears AddressLine4 and resets StateCode = "OR", CountryCode = "US". The StateCode setter itself derives CountryCode: blank state clears the country, a nonblank state sets "US".
  13. Insert. BeforeInsert writes TAX_ID, TAX_ID_DISPLAY_DESCR, PROVIDER_SEQ_NUM, REGISTERED_NAME/REGISTERED_NAME_UPPER_CASE, EFF_DATE/EXP_DATE, W9_SENT_DATE/W9_RECEIVED_DATE, REPORT_1099_FLAG, address fields, FOREIGN_ADDRESS_FLAG, and audit fields to PROVIDER_TAX_ID (SQL-036).
  14. FillTinContact() builds TaxDto { providerNumber, tinId = TaxID, tinNumber = TaxIDDisplayDescr }.
  15. On a rows-affected value other than 1: add "Insert Failed".
  16. On success, only if PrimaryTaxIDFlag = "Y": call clsTaxApi.UpdateTinContact(...) against route provider/{taxDto.ProviderNumber}/tin; on exception, serialize the DTO, log it, and add ApiInsertError.
  17. Update. BeforeUpdate writes the same fields to PROVIDER_TAX_ID (SQL-084) with concurrency check on UPDATE_NUM.
  18. On success, if primary: call clsTaxApi.UpdateTinContact(...); on API exception, log and add ApiUpdateError.
  19. Delete. Deletes the PROVIDER_TAX_ID row by TAX_ID (SQL-106) — no ContactManager sync call is made on delete, unlike insert/update for the primary TIN.*
  20. Payment-history helper (not gated by a rule). HasPayment calls clsPaymentApi.GetPayments twice — once with an EIN-formatted TIN (00-0000000) and once with an SSN-formatted TIN (000-00-0000) — but no business rule in this file consumes the result, so it functions as an on-demand check available to callers rather than an enforced save-time gate.*

Process flow

flowchart TD
    Start([Caller edits tax ID]) --> Altered{Existing TIN digits changed?}
    Altered -->|Yes| Fail([Immutable TIN change<br>blocks save])
    Altered -->|No| FormatCheck{Numeric, 9+ digits,<br>matches EIN/SSN mask?}
    FormatCheck -->|No| Fail2([Invalid format or<br>duplicate blocks save])
    FormatCheck -->|Yes| DupCheck{Duplicate TIN on file?}
    DupCheck -->|Yes| Fail2
    DupCheck -->|No| PrimaryCheck{Marked primary and<br>another primary exists?}
    PrimaryCheck -->|Yes| Fail3([Second primary<br>TIN blocks save])
    PrimaryCheck -->|No| Clean[Normalize address;<br>warning only]
    Clean --> Persist[Insert/update/delete PROVIDER_TAX_ID]
    Persist --> Rows{RowsAffected = 1?}
    Rows -->|No| Contention([Insert Failed / DB contention error])
    Rows -->|Yes| PrimaryFlag{PrimaryTaxIDFlag = Y?}
    PrimaryFlag -->|Yes, insert/update| Api[Call clsTaxApi.UpdateTinContact]
    PrimaryFlag -->|No, or delete| NoApi([No ContactManager call])
    Api --> Done([Save complete])
    NoApi --> Done

Failure and edge-case behavior

  • Deleting a tax ID never calls ContactManager, so a removed TIN can remain visible there until a subsequent primary-TIN save elsewhere triggers a sync.*
  • Only the primary TIN synchronizes to ContactManager; non-primary TIN inserts/updates persist to the database with no external side effect.
  • HasPayment exists as a read-only helper but is not wired into any enforced business rule in this file, so its use is caller-driven.*
  • USPS address cleansing on a tax ID's mailing address is warning-only and never blocks the save, mirroring the pattern used for provider addresses.

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\clsProviderTaxID.vb
  • Business\SAIF.Business.Provider\Api\clsTaxApi.vb
  • Business\SAIF.Business.Provider\Api\clsPaymentApi.vb