Skip to content

EFT record management

clsProviderEFT represents one provider location's PROVIDER_EFT_INTERFACE row: which external user administers the location's electronic funds transfer preference, when that administration window is effective, and whether the location defaults to its primary payment method. Retrieval, creation, update, and deletion of this record share the same optimistic-concurrency behavior, so they are documented as a single operation; assigning or unassigning the underlying payment preference itself is a separate, related operation.

Field Value
Operation ID OP-PP-02
Trigger Caller invokes GetProviderEFT/NewProviderEFT, edits the returned object, and calls Save()
Inputs ProviderSeqNum, ProviderLocationSeqNum, ExtUserTypeSeqNum, EffDate, ExpDate, defaultToPrimaryFlag
Outputs Populated clsProviderEFT; persisted PROVIDER_EFT_INTERFACE row on save; InsertError/DBContentionError on save failure
Primary components clsProviderEFT.GetProviderEFT, clsProviderEFT.NewProviderEFT, clsProviderEFT.BeforeRetrieve/AfterRetrieve, clsProviderEFT.BeforeInsert/AfterInsert, clsProviderEFT.BeforeUpdate/AfterUpdate, clsProviderEFT.BeforeDelete/AfterDelete, clsProviderEFT.SetExtUserTypeSeqNum
Entry point Business\SAIF.Business.Provider.PaymentPreference\clsProviderEFT.vb

Steps

  1. Retrieve. GetProviderEFT(dpi, providerSeqNum, providerLocationSeqNum) builds a Criteria and fetches the row by both keys, joined to the external-user/person chain for display (SQL-008, PROVIDER_EFT_INTERFACE, EXT_USER_TYPE, EXT_USER, PERSON).
  2. AfterRetrieve fills the first row and always calls MarkOld() — unlike clsProviderEOB, there is no UpdateNum = 0 New/Old determination here; a retrieved object is always considered persisted.*
  3. Create. NewProviderEFT(dpi, providerSeqNum, providerLocSeqNum) constructs a new object; Create() seeds the keys, update user, and update date from the criteria and data-portal info.
  4. Insert. BeforeInsert sets UpdateDate/UpdateUser/UpdateNum = 1, and if ExtUserTypeSeqNum is empty calls SetExtUserTypeSeqNum() to derive it from context (BR-11).
  5. AfterInsert executes the insert (SQL-003, PROVIDER_EFT_INTERFACE) and checks the rows-affected count.
    • On a rows-affected value other than 1: add InsertError ("Insert Failed") (BR-12).
    • On success: save the child payment-preference object(s) held in m_StartingProviderPaymentPreference/m_NewProviderPaymentPreference (see EFT payment location assignment), then MarkOld() (BR-12).
  6. Update. BeforeUpdate refreshes UpdateDate/UpdateUser, re-derives ExtUserTypeSeqNum via SetExtUserTypeSeqNum() when it is empty or zero (BR-11), and defaults EffDate to today if it is still Date.MinValue (BR-16).
  7. AfterUpdate executes the update (SQL-014, PROVIDER_EFT_INTERFACE) and checks the rows-affected count.
    • On a rows-affected value other than 1: add DBContentionError (BR-13).
    • On success: increment the in-memory UpdateNum, save the child payment-preference object(s), then MarkOld() (BR-13).
  8. Delete. BeforeDelete binds the provider/location keys; AfterDelete executes the delete (SQL-016, PROVIDER_EFT_INTERFACE).
  9. On a rows-affected value other than 1: add DBContentionError.
  10. On success: MarkNew().
  11. Save wrapper. Save() calls ApplyEdit() before delegating to the BOF base save (which routes to steps 3–5 depending on object state), and returns ErrorCount = 0.

Process flow

flowchart TD
    Start([Caller requests EFT record]) --> Retrieve[Retrieve by provider + location]
    Retrieve --> MarkOld1[MarkOld regardless of UpdateNum]
    Start2([Caller creates new EFT]) --> Create[Create: seed keys, update user, update date]
    Create --> Edit[Caller edits fields<br>and optionally assigns payment preference]
    MarkOld1 --> Edit
    Edit --> State{Object state?}
    State -->|New| Insert[Insert: UpdateNum = 1,<br>derive ExtUserTypeSeqNum]
    State -->|Modified| Update[Update: derive ExtUserTypeSeqNum,<br>default EffDate to today]
    State -->|Removed| Delete[Delete by provider + location]
    Insert --> Rows1{RowsAffected = 1?}
    Update --> Rows2{RowsAffected = 1?}
    Delete --> Rows3{RowsAffected = 1?}
    Rows1 -->|No| ErrIns([InsertError added])
    Rows1 -->|Yes| SaveChild1[Save child payment preference]
    Rows2 -->|No| ErrUpd([DBContentionError added])
    Rows2 -->|Yes| IncNum[Increment in-memory UpdateNum]
    IncNum --> SaveChild2[Save child payment preference]
    Rows3 -->|No| ErrDel([DBContentionError added])
    Rows3 -->|Yes| MarkNew([MarkNew])
    SaveChild1 --> Old([MarkOld])
    SaveChild2 --> Old

Failure and edge-case behavior

  • Insert and update both treat any rows-affected value other than 1 as a failure, adding an error instead of throwing; the child payment-preference object is only saved after the parent EFT row itself persists successfully.
  • AfterRetrieve unconditionally marks the object Old, so a GetProviderEFT call for a provider location that has never had a row returns an object with all-default field values that still behaves as "existing" until the caller inspects the data — there is no analogous New/Old signal to the one clsProviderEOB derives from UpdateNum.*
  • SetExtUserTypeSeqNum is history-sensitive: it clears the value when the record is being expired or no admin user is available, but sets it from an explicit override or the ambient admin user otherwise (BR-11); the same method also runs implicitly whenever EFT payment location assignment sets ExtUserTypeSeqNum.
  • If EffDate is left at Date.MinValue going into an update, it is silently defaulted to today rather than surfaced as a validation error (BR-16).

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.PaymentPreference\clsProviderEFT.vb