---
title: EFT payment location assignment
summary: Assigns a new payment preference (direct deposit or check) to a provider location's EFT record, or unassigns it back to paper check, revoking the prior authorization as needed.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-07-30
library: SAIF.Business.Provider.PaymentPreference
reference_type: package
operation_id: OP-PP-03
trigger: Caller sets ProviderPaymentPreference (via AssignPaymentLocation) or calls UnAssignPaymentLocation/UnAssignPaymentLoc on a clsProviderEFT
---

# EFT payment location assignment

Assignment and unassignment are the two mutually related transitions that change how a provider location is paid. Assigning attaches a new `clsProviderPaymentPreference` (direct deposit or check) to the location's `clsProviderEFT` and, if an active direct-deposit authorization already exists, revokes it first. Unassigning reverts the location to paper check by expiring the EFT record and revoking whichever authorization is currently pending. Both paths funnel through the same `ProviderPaymentPreference` property and `RevokeAuthorization` helper, so they are documented together.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-PP-03 |
| **Trigger** | `AssignPaymentLocation(newPreference, [userSeqNum])` or `UnAssignPaymentLocation`/`UnAssignPaymentLoc` on a retrieved or new `clsProviderEFT` |
| **Inputs** | New `clsProviderPaymentPreference` (direct deposit or check), optional acting user sequence number |
| **Outputs** | Updated `ProviderPaymentPreference`, `EffDate`, `ExpDate`; revoked prior `clsEFTAuthorization` when applicable; customer email-notification fields populated |
| **Primary components** | `clsProviderEFT.ProviderPaymentPreference` (property setter), `clsProviderEFT.AssignPaymentLocation`, `clsProviderEFT.UnAssignPaymentLocation`, `clsProviderEFT.UnAssignPaymentLoc`, `clsProviderEFT.RevokeAuthorization` |
| **Entry point** | `Business\SAIF.Business.Provider.PaymentPreference\clsProviderEFT.vb` |

## Steps

1. **Load the current preference (lazily).** The `ProviderPaymentPreference` getter returns the pending new preference if one has already been set this session; otherwise it lazily retrieves the starting preference via `clsProviderPaymentPreference.GetPaymentPreference(dpi, 0, ProviderLocationSeqNum, IsUserSAIFEmployee, MaskBankNumbers, BankValidatorXML)` and, if that preference is direct deposit, registers it as a child object.
   - Sub-step: `GetPaymentPreference` resolves the location's current payment-preference type (Check, DirectDeposit, DebitCard, or Unspecified) and, for direct deposit, loads the associated `clsEFTAuthorization` and its `clsBankAccount`.

   > **Origin**: `clsProviderPaymentPreference` and its authorization/bank-account retrieval are implemented in `SAIF.Business.Payment.EFT` and executed on behalf of this operation. That library is documented in the previous format, so no per-operation page exists; see [Payment preference selection](../../saif-business-payment-eft/operations/payment-preference-selection.md) and [Bank account management](../../saif-business-payment-eft/operations/bank-account-management.md) in the `SAIF.Business.Payment.EFT` documentation set.
2. **Assign a new preference.** `AssignPaymentLocation(inNewPaymentPreference, [inUserSeqNum])` sets `ProviderPaymentPreference = inNewPaymentPreference`, sets `EffDate = Today`, clears `ExpDate`, always flags the new authorization's `CustomerEmailNotificationFlag = "Y"` and copies `CustomerContactEmailAddress` from `ExtUserEmailAddr` ([BR-09](../business-rules.md#br-09-on-assignpaymentlocation-customeremailnotificationflag-is-always-set-to-y-and-customercontactemailaddress-is-populated-from-extuseremailaddr-ensuring-the-customer-receives-notification-of-an-eft-assignment)), and — if a positive user sequence number is supplied — sets `ExtUserTypeSeqNum` to it.
   - `ExtUserEmailAddr` is populated only when the collection-level query that produced this object was `GetProviderEFTLocEmails` ([SQL-012](../sql/SQL-012-select-provider-eft-locations-with-external-user-email.md)); see [Provider EFT collection retrieval](provider-eft-collection-retrieval.md).
3. **Assign — replace an existing authorization.** The `ProviderPaymentPreference` setter inspects the *starting* preference before overlaying the new one:
   - If the starting preference is new (unsaved) or is currently a Check-type: simply overlay it with the incoming value and register the new value as a child object — no revocation needed ([BR-08](../business-rules.md#br-08-when-assigning-a-new-payment-preference-to-an-eft-that-is-already-saved-and-currently-direct-deposit-the-existing-authorization-is-revoked-before-the-new-one-is-applied-if-the-existing-eft-is-new-unsaved-or-is-a-check-type-it-is-simply-overwritten)).
   - Otherwise (a saved, active direct-deposit preference is being replaced): call `RevokeAuthorization` on the *starting* preference (step 5) before storing the new preference as `m_NewProviderPaymentPreference` and registering it as a child object ([BR-08](../business-rules.md#br-08-when-assigning-a-new-payment-preference-to-an-eft-that-is-already-saved-and-currently-direct-deposit-the-existing-authorization-is-revoked-before-the-new-one-is-applied-if-the-existing-eft-is-new-unsaved-or-is-a-check-type-it-is-simply-overwritten)).
   - In either branch, the setter marks the EFT object dirty in a `Finally` block, guaranteeing the dirty flag is set even if revocation raises.
4. **Unassign.** `UnAssignPaymentLocation` sets `ExpDate = Today` and then revokes whichever preference is pending: if a new preference was already staged in this session (`m_NewProviderPaymentPreference`), that one is revoked; otherwise the starting preference is revoked ([BR-10](../business-rules.md#br-10-on-unassignpaymentlocation-expdate-is-set-to-today-and-the-active-authorization-is-revoked-for-saif-employees-isusersaifemployee-true-authorization-is-revoked-with-false-internal-path-for-non-employees-with-true-external-path)). `UnAssignPaymentLoc` is a boolean-returning wrapper that always calls `UnAssignPaymentLocation` and returns `True`.
5. **Revoke authorization.** `RevokeAuthorization(preference)`:
   - Returns immediately (no-op) if the preference is `Nothing`.
   - Returns immediately if the preference `IsNew` (never persisted, so nothing to revoke).
   - Returns immediately if the preference's type is not `DirectDeposit` (a Check preference has no authorization to revoke).
   - Otherwise calls `preference.PaymentAuthorization.RevokeAuthorization(False)` for SAIF employees or `RevokeAuthorization(True)` for external users ([BR-10](../business-rules.md#br-10-on-unassignpaymentlocation-expdate-is-set-to-today-and-the-active-authorization-is-revoked-for-saif-employees-isusersaifemployee-true-authorization-is-revoked-with-false-internal-path-for-non-employees-with-true-external-path)), then marks the EFT object dirty.

   > **Origin**: `clsEFTAuthorization.RevokeAuthorization` is implemented in `SAIF.Business.Payment.EFT` and executed on behalf of this operation. That library is documented in the previous format, so no per-operation page exists; see [EFT authorization / consent](../../saif-business-payment-eft/operations/eft-authorization-consent.md) in the `SAIF.Business.Payment.EFT` documentation set.
6. **Persist.** The staged preference change is not written to the database until the parent `clsProviderEFT.Save()` runs; see steps 3–4 of [EFT record management](eft-record-management.md), which saves `m_StartingProviderPaymentPreference`/`m_NewProviderPaymentPreference` as child objects only after the EFT row itself is successfully inserted or updated.

## Process flow

```mermaid
flowchart TD
	Start([Caller assigns or unassigns]) --> Which{Assign or unassign?}
	Which -->|Assign| Load[Lazily load starting<br>ProviderPaymentPreference]
	Load --> SetFields[Set EffDate = Today,<br>clear ExpDate, flag email notification]
	SetFields --> Check{Starting preference new<br>or Check-type?}
	Check -->|Yes| Overlay[Overlay with new preference]
	Check -->|No, active DirectDeposit| Revoke1[Revoke starting authorization]
	Revoke1 --> Stage[Stage new preference as<br>NewProviderPaymentPreference]
	Overlay --> Dirty1([Mark EFT dirty])
	Stage --> Dirty1
	Which -->|Unassign| SetExp[Set ExpDate = Today]
	SetExp --> WhichPending{New preference<br>already staged?}
	WhichPending -->|Yes| Revoke2[Revoke staged new preference]
	WhichPending -->|No| Revoke3[Revoke starting preference]
	Revoke2 --> Dirty2([Mark EFT dirty])
	Revoke3 --> Dirty2
	Dirty1 --> Save[EFT record management: Save persists<br>EFT row then child preference]
	Dirty2 --> Save
```

## Failure and edge-case behavior

- `RevokeAuthorization` is defensively guarded: a `Nothing` preference, a new (unsaved) preference, and a non-direct-deposit preference are all silent no-ops rather than errors.
- Because the setter distinguishes revoke-then-replace from simple-overlay purely by whether the *starting* preference `IsNew` or is Check-type, assigning a brand-new direct-deposit preference on top of an unsaved EFT record never triggers a revocation call, even if the caller passes a different preference object on a second call within the same session.*
- `UnAssignPaymentLocation` prefers revoking the newly staged preference over the starting one when both exist in the same session, so a caller that assigns and then immediately unassigns within one edit session never revokes the original starting authorization directly — only whichever preference is currently considered "current."*
- Revocation behavior differs by actor: SAIF employees revoke with the internal (`False`) path while external users revoke with the external (`True`) path ([BR-10](../business-rules.md#br-10-on-unassignpaymentlocation-expdate-is-set-to-today-and-the-active-authorization-is-revoked-for-saif-employees-isusersaifemployee-true-authorization-is-revoked-with-false-internal-path-for-non-employees-with-true-external-path)); the semantic difference between the two paths is implemented entirely inside `SAIF.Business.Payment.EFT` and is not visible from this library's source.*

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [SQL catalog](../sql/index.md)
- [Database tables](../database-tables.md)

> **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`
