EOB preference management¶
clsProviderEOB represents one provider location's paperless-EOB (Explanation of Benefits) delivery preference — which external user receives EOB correspondence and whether delivery is electronic or paper. clsProviderEOBCollection lists every location for a provider, including locations that have never configured a preference, by left-outer-joining PROVIDER_LOCATION to PROVIDER_EOB_INTERFACE. Retrieval, creation, update, and deletion all share the same optimistic-concurrency and default-flag rules, so they are documented together.
| Field | Value |
|---|---|
| Operation ID | OP-PP-01 |
| Trigger | Caller invokes GetProviderEOBs/NewProviderEOBs (collection) or GetProviderEOB/NewProviderEOB (single object), edits the returned object(s), and calls Save() |
| Inputs | ProviderSeqNum, ProviderLocationSeqNum, ExtUserTypeSeqNum, PaperlessEOBFlag, DefaultPrimaryFlag |
| Outputs | Populated clsProviderEOB / clsProviderEOBCollection; persisted PROVIDER_EOB_INTERFACE row on save; InsertError/DBContentionError on save failure |
| Primary components | clsProviderEOB.GetProviderEOB, clsProviderEOB.NewProviderEOB, clsProviderEOB.BeforeInsert/AfterInsert, clsProviderEOB.BeforeUpdate/AfterUpdate, clsProviderEOB.BeforeDelete/AfterDelete, clsProviderEOBCollection.GetProviderEOBs/NewProviderEOBs, clsProviderEOBCollection.AfterRetrieve |
| Entry point | Business\SAIF.Business.Provider.PaymentPreference\clsProviderEOB.vb, Business\SAIF.Business.Provider.PaymentPreference\clsProviderEOBCollection.vb |
Steps¶
- Retrieve the collection for a provider.
GetProviderEOBs/NewProviderEOBs(dpi, providerSeqNum)build aCriteriaand fetch every location for the provider, left-outer-joined to any existingPROVIDER_EOB_INTERFACErow and the external-user/email/person chain (SQL-007, PROVIDER_LOCATION, PROVIDER_EOB_INTERFACE, EXT_USER_TYPE, EXT_USER, EMAIL_ADDRESS, PERSON). AfterRetrieveiterates each row, constructs a newclsProviderEOB, and calls itsLoadmethod to fill it from that row before adding it to the collection.- Fill each row and determine new-vs-old state.
Fill()copies all columns onto the object, and the constantUserNamefallback resolves toPAPER_EOB("Paper EOB") whenever the joined person name is blank, signaling no external user is linked (BR-17). Fill()marks the object New whenUpdateNum = 0and Old otherwise, so a location with no prior EOB preference row (left-outer-joined nulls) is still returned as an editable object that will Insert rather than Update on save (BR-18).- Retrieve a single preference.
GetProviderEOB(dpi, providerSeqNum, providerLocationSeqNum)builds aCriteriaand fetches one row. - If
ProviderSeqNum <> 0:BeforeRetrievebinds bothProviderSeqNumandProviderLocationSeqNumand issues the by-provider-and-location query (SQL-005, PROVIDER_EOB_INTERFACE). - If
ProviderSeqNum = 0:BeforeRetrievebinds onlyProviderLocationSeqNumand issues the location-only variant instead (SQL-006). AfterRetrievefills the first returned row, applying the same New/Old determination as step 2 (BR-18).- Create.
NewProviderEOB(dpi, providerSeqNum, providerLocationSeqNum)constructs a new object andCreate()seeds the keys, update user, and defaultsPaperlessEOBFlag/DefaultPrimaryFlagto"N". BeforeInsertre-derivesPaperlessEOBFlag:"Y"only whenExtUserTypeSeqNumis populated and non-zero at insert time, otherwise"N"(BR-01);DefaultPrimaryFlagis always reset to"N"on insert regardless of any caller-set value (BR-02).AfterInsertexecutes the insert (SQL-001, PROVIDER_EOB_INTERFACE) and checks the rows-affected count.- On a rows-affected value other than
1: addInsertError("Insert Failed") and leave the object marked New (BR-03). - On success:
MarkOld().
- On a rows-affected value other than
- Update.
BeforeUpdaterefreshesUpdateDate/UpdateUserand binds all mutable fields plus the in-memoryUpdateNumas aWHEREpredicate. AfterUpdateexecutes the update, which incrementsUPDATE_NUMat the database and requires the boundUpdateNumto match the current row (SQL-013, PROVIDER_EOB_INTERFACE).- On a rows-affected value other than
1: addDBContentionError(BR-04). - On success:
MarkOld(). - Note: unlike
clsProviderEFT.AfterUpdate,clsProviderEOB.AfterUpdatedoes not increment the in-memoryUpdateNumafter a successful update, even though the database value advances; a subsequent update against the same in-memory instance would then fail contention until the object is re-retrieved.*
- On a rows-affected value other than
- Delete.
BeforeDeletebinds the provider/location keys;AfterDeleteexecutes the delete (SQL-015, PROVIDER_EOB_INTERFACE). - On a rows-affected value other than
1: addDBContentionError(BR-05). - On success:
MarkNew(). - Collection save.
clsProviderEOBCollection.Save()callsApplyEdit()and delegates to the base collection save, which persists each changed childclsProviderEOBthrough steps 4–6.
Process flow¶
flowchart TD
Start([Caller requests EOB preference]) --> Which{Single or collection?}
Which -->|Collection| ListQ[Query provider locations<br>left-joined to PROVIDER_EOB_INTERFACE]
ListQ --> Fill1[Fill each row;<br>UpdateNum = 0 marks New]
Which -->|Single, ProviderSeqNum not 0| ByBoth[Query by provider + location]
Which -->|Single, ProviderSeqNum is 0| ByLoc[Query by location only]
ByBoth --> Fill2[Fill row; UpdateNum = 0 marks New]
ByLoc --> Fill2
Fill1 --> Edit[Caller edits fields]
Fill2 --> Edit
Edit --> IsNew{Object marked New?}
IsNew -->|Yes| Insert[Insert: derive PaperlessEOBFlag,<br>reset DefaultPrimaryFlag]
IsNew -->|No, edited| Update[Update with UpdateNum<br>as WHERE predicate]
IsNew -->|No, 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| Old([MarkOld])
Rows2 -->|No| ErrUpd([DBContentionError added])
Rows2 -->|Yes| Old
Rows3 -->|No| ErrDel([DBContentionError added])
Rows3 -->|Yes| New([MarkNew])
Failure and edge-case behavior¶
- Insert, update, and delete all treat any rows-affected value other than
1as a failure and add an error message instead of throwing; the object's in-memory state (New/Old) only advances on success. clsProviderEOB.AfterUpdatenever increments the in-memoryUpdateNumon success, unlike the EFT object's equivalent hook; reusing the same in-memory instance for a second update without re-retrieving it will likely fail theWHERE UPDATE_NUM = :UpdateNumpredicate and surface a false contention error.*- Because the collection query left-outer-joins every provider location, a provider with no configured EOB preference for a location still yields a row (all EOB columns null) rather than omitting it;
UpdateNum = 0on that null row is what causes the object to be treated as New (BR-18). clsProviderEOB's ownCriteria.RetrieveSQL/RetrieveSqlLocselection is driven purely by whether the caller passedProviderSeqNum = 0; passing an explicit0is the only way to reach the location-only query.
Related documentation¶
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\clsProviderEOB.vbBusiness\SAIF.Business.Provider.PaymentPreference\clsProviderEOBCollection.vb