---
title: SAIF.Business.Claim.EAIP business rules
summary: Business rules enforced by SAIF.Business.Claim.EAIP.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-07-30
library: SAIF.Business.Claim.EAIP
reference_type: package
---

# SAIF.Business.Claim.EAIP business rules

This page captures business rules enforced by `SAIF.Business.Claim.EAIP`.

## BR-PROC-001: Protect expense status changes with optimistic concurrency

| Field | Value |
| --- | --- |
| Statement | Protect expense status changes with optimistic concurrency |
| Trigger | EX.UPDATE_NUM = LastUpdateNum |
| Enforcement | pk82500_eaip.update_expense_status |
| Outcome | Return SQL%ROWCOUNT so callers detect stale updates |
| Confidence | Source-backed |
| Source | [pk82500_eaip.update_expense_status](procedures/pk82500_eaip.md#update_expense_status) |

---

## BR-PROC-002: Protect EAIP period updates with optimistic concurrency

| Field | Value |
| --- | --- |
| Statement | Protect EAIP period updates with optimistic concurrency |
| Trigger | UPDATE_NUM must match LastUpdateNum |
| Enforcement | pk82500_eaip.eaip_period_update |
| Outcome | Return SQL%ROWCOUNT instead of forcing the update |
| Confidence | Source-backed |
| Source | [pk82500_eaip.eaip_period_update](procedures/pk82500_eaip.md#eaip_period_) |

---

## BR-PROC-003: Return only credit-card purchases paid for the selected EAIP user

| Field | Value |
| --- | --- |
| Statement | Return only credit-card purchases paid for the selected EAIP user |
| Trigger | PR.CREDIT_CARD_PAID_DATE is not null and PR.CREDIT_CARD_USER = EaipUser |
| Enforcement | pk82500_eaip.credit_payment_select |
| Outcome | Expose only supervisor-review candidates for that user |
| Confidence | Source-backed |
| Source | [pk82500_eaip.credit_payment_select](procedures/pk82500_eaip.md#credit_payment_select) |

---

## BR-PROC-004: Clean up orphan EAIP expenses after deleting a period

| Field | Value |
| --- | --- |
| Statement | Clean up orphan EAIP expenses after deleting a period |
| Trigger | Deleted period leaves EAIP_EXPENSE rows without EAIP_PURCHASE or EAIP_WAGE_SUBSIDY parents |
| Enforcement | pk82500_eaip.eaip_period_delete |
| Outcome | Delete orphan expense rows |
| Confidence | Source-backed |
| Source | [pk82500_eaip.eaip_period_delete](procedures/pk82500_eaip.md#eaip_period_) |

---

## BR-PROC-005: Expense payments over the user authority level require supervisor approval

| Field | Value |
| --- | --- |
| Statement | Expense payments over the user authority level require supervisor approval |
| Trigger | A dirty expense is moved toward payment and the acting user lacks initiate authority for the paid amount, or an amendment is entered without approval authority, or the paid amount exceeds the expense type's limit amount |
| Enforcement | `clsExpense.NeedsApproval` and `clsExpense.CanPay`, using `PaymentUser.HasInitiateAuthority` and `PaymentUser.HasApprovalAuthority` |
| Outcome | The expense is demoted to pending supervisor approval instead of moving to pay status |
| Confidence | Source-backed |
| Source | `Business\SAIF.Business.Claim.EAIP\Period\clsExpense.vb` (`NeedsApproval`, `CanPay`, `Rule_HasInitiateAuthority`) |

---

## BR-PROC-006: Credit-card purchases always require supervisor approval

| Field | Value |
| --- | --- |
| Statement | Credit-card purchases always require supervisor approval |
| Trigger | A purchase in pay status carries a credit-card transaction date |
| Enforcement | `clsPurchase.NeedsApproval` override, which returns true before any authority or limit evaluation and adds the warning "Supervisor approval is required when credit card trans date is entered." |
| Outcome | The purchase is routed to the supervisor credit-card review queue regardless of amount or user authority |
| Confidence | Source-backed |
| Source | `Business\SAIF.Business.Claim.EAIP\Period\clsPurchase.vb` (`NeedsApproval`, `CreditCardPaidDate`) |

---

## BR-PROC-007: Wage subsidy pay equals gross wages times the effective rate factor

| Field | Value |
| --- | --- |
| Statement | Wage subsidy pay equals gross wages times the effective rate factor |
| Trigger | A wage subsidy worksheet is recalculated from its pay period summaries |
| Enforcement | `clsWageSubsidy` sets gross wages to the sum of the pay period gross wages and the paid amount to that sum multiplied by `WageSubsidyCalculationFactor`, rounded to two decimals |
| Outcome | The payable wage subsidy is a derived value that cannot be entered directly |
| Confidence | Source-backed |
| Source | `Business\SAIF.Business.Claim.EAIP\Period\clsWageSubsidy.vb` (`WageSubsidyCalculationFactor`, worksheet recalculation) |

---

## BR-PROC-008: Wage subsidy days may not exceed 66 in a service period

| Field | Value |
| --- | --- |
| Statement | Wage subsidy days may not exceed 66 in a service period |
| Trigger | The summed days of the non-amended, non-denied wage subsidies on a service period exceed 66 |
| Enforcement | `clsWageSubsidyCollection` adds the warning "Warning: Supervisor approval is required when paying more than 66 days."; the related rule `Rule_Rule_ValidDaySpanInTwoYears` warns that the 66 days must fall within the 24-month service period |
| Outcome | Payment is blocked until a supervisor approves the excess |
| Confidence | Source-backed |
| Source | `Business\SAIF.Business.Claim.EAIP\Period\clsWageSubsidy.vb` (collection `CanPay`, `Rule_Rule_ValidDaySpanInTwoYears`) |

---

## BR-PROC-009: Expense payment totals under $100 require supervisor approval

| Field | Value |
| --- | --- |
| Statement | Expense payment totals under $100 require supervisor approval |
| Trigger | Any expense on the service period sits in pay status and the summed paid amount is less than the $100 minimum, and the total cannot be billed |
| Enforcement | `clsExpenseCollection.CanPay` compares the summed paid amount against the `MIN_PAID_AMOUNT` constant of 100 and adds the warning "Warning: Supervisor approval is needed when payment total is less than $100.00." |
| Outcome | The payment run is blocked until a supervisor approves the small-dollar total |
| Confidence | Source-backed |
| Source | `Business\SAIF.Business.Claim.EAIP\Period\clsExpense.vb` (`MIN_PAID_AMOUNT`, `clsExpenseCollection.CanPay`) |

---

## BR-PROC-010: Only the first bill for a service period carries the administrative fee

| Field | Value |
| --- | --- |
| Statement | Only the first bill for a service period carries the administrative fee |
| Trigger | A DCBS bill is generated for a service period whose existing bills already sum to a non-zero administrative fee |
| Enforcement | `clsGenerateBill.GenerateBill` sums `AdminFeeAmount` across the period's existing bills; a zero sum produces an initial bill carrying the admin-fee limit amount from the EAIP type code table, and a non-zero sum produces a subsequent bill with no fee |
| Outcome | The administrative fee is billed to DCBS once per service period |
| Confidence | Source-backed |
| Source | `Business\SAIF.Business.Claim.EAIP\Billing\clsGenerateBill.vb` (`GenerateBill`, `AdminFee`) |

---

## BR-PROC-011: Amended expenses are excluded from the batch billing run

| Field | Value |
| --- | --- |
| Statement | Amended expenses are excluded from the batch billing run |
| Trigger | The batch bill run finds paid wage subsidies or purchases carrying a non-zero original expense identifier |
| Enforcement | `clsGenerateBill.GenerateBill` returns an empty bill immediately when `billAmended` is false and amendments were detected, with the code comment "don't bill amendments during batch run" |
| Outcome | Amendments and corrections are billed only through the explicit on-demand path, which also generates a cover letter |
| Confidence | Source-backed |
| Source | `Business\SAIF.Business.Claim.EAIP\Billing\clsGenerateBill.vb` (`GenerateBill`, `GenCoverLetter`) |

---

## BR-PROC-012: A reimbursement detail reconciles only when amounts match the detail total

| Field | Value |
| --- | --- |
| Statement | A reimbursement detail reconciles only when amounts match the detail total |
| Trigger | The DCBS balancing run finishes matching a reimbursement detail's expense-type amounts against the claim's unreconciled billed expenses |
| Enforcement | `clsBalanceDCBS.BalanceToDCBS` compares the detail's total amount with the accumulated matched amount; equality sets the reconciled flag and increments the reconciled counter, and any difference increments the skipped counter and emits a "Not Reconciled" warning. The detail's transaction is committed only when the reconciled flag is set |
| Outcome | Partial matches are rolled back rather than persisted, so a detail is either fully reconciled or left untouched |
| Confidence | Source-backed |
| Source | `Business\SAIF.Business.Claim.EAIP\Reimbursement\clsBalanceDCBS.vb` (`BalanceToDCBS`, `ProcessOneBatch`) |

---

## BR-PROC-013: EAIP service periods for a claim may not overlap

| Field | Value |
| --- | --- |
| Statement | EAIP service periods for a claim may not overlap |
| Trigger | A service period's effective or expiration date is set so that its range intersects another period on the same claim |
| Enforcement | `clsPeriod.Rule_ValidServiceDates` tests the candidate date range against the claim's other periods and reports "Error: Period dates overlap an existing period." |
| Outcome | The overlapping period cannot be saved |
| Confidence | Source-backed |
| Source | `Business\SAIF.Business.Claim.EAIP\Period\clsPeriod.vb` (`Rule_ValidServiceDates`) |

---

## BR-PROC-014: Targeting records must be unique by claim, status date, and completed date

| Field | Value |
| --- | --- |
| Statement | Targeting records must be unique by claim, status date, and completed date |
| Trigger | A targeting record is saved whose claim identifier, claim status effective date, and completed date match another record |
| Enforcement | `clsTargeting.Rule_ValidUniqueID` counts matching rows in the EAIP claim targeting table excluding the record's own identifier, and the collection rules `Rule_ValidUniqueIDs` and `Rule_DuplicateTargetings` group the in-memory records on the same three values |
| Outcome | Duplicate eligibility screenings are rejected, whether the duplicate is already stored or still pending in the same collection |
| Confidence | Source-backed |
| Source | `Business\SAIF.Business.Claim.EAIP\Targeting\clsTargeting.vb` (`Rule_ValidUniqueID`, `Rule_ValidUniqueIDs`, `Rule_DuplicateTargetings`) |

---

## BR-PROC-015: Timecard regular and overtime hours must equal calculated hours

| Field | Value |
| --- | --- |
| Statement | Timecard regular and overtime hours must equal calculated hours |
| Trigger | A timecard's regular hours are entered or changed |
| Enforcement | `clsPayPeriodTimeCard.Rule_ValidTotalHours` requires regular plus overtime hours to equal the calculated hours derived from the in and out times, reporting both figures in the message |
| Outcome | The timecard cannot be saved until the entered split agrees with the elapsed time worked |
| Confidence | Source-backed |
| Source | `Business\SAIF.Business.Claim.EAIP\Period\clsPayPeriodTimeCard.vb` (`Rule_ValidTotalHours`, `CalculatedHours`) |

## Notes
- Procedure-derived rules are mirrored here so claim-domain readers do not have to open procedure pages to see active constraints.
- Rules without BOF rule attributes are enforced by lifecycle methods, helper methods, or stored-procedure contracts.

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Dependencies](dependencies.md)
- [Operations and processes](operations-processes.md)
- [Database tables](database-tables.md)
- [SQL catalog](sql/index.md)
- [Procedures](procedures/index.md)
- [API reference](api/index.md)

## Sources
- `Business\SAIF.Business.Claim.EAIP\SAIF.BOF.Business.Claim.EAIP.vbproj`
- `Business\SAIF.Business.Claim.EAIP\SAIF.BOF.Business.Claim.EAIP.nuspec`
- `Business\SAIF.Business.Claim.EAIP\packages.config`
- `Business\SAIF.Business.Claim.EAIP\Pipelines\build-vars.yml`
- `Business\SAIF.Business.Claim.EAIP\Billing\clsBilling.vb`
- `Business\SAIF.Business.Claim.EAIP\Billing\clsExpenseBilling.vb`
- `Business\SAIF.Business.Claim.EAIP\Billing\clsGenerateBill.vb`
- `Business\SAIF.Business.Claim.EAIP\Period\clsPayPeriod.vb`
- `Business\SAIF.Business.Claim.EAIP\Period\clsPayPeriodTimeCard.vb`
- `Business\SAIF.Business.Claim.EAIP\Period\clsPeriod.vb`
- `Business\SAIF.Business.Claim.EAIP\Period\clsExpense.vb`
- `Business\SAIF.Business.Claim.EAIP\Period\clsPurchase.vb`
- `Business\SAIF.Business.Claim.EAIP\Period\clsCreditCardPayments.vb`
- `Business\SAIF.Business.Claim.EAIP\Period\clsWageSubsidy.vb`
- `Business\SAIF.Business.Claim.EAIP\Reimbursement\clsReimbursement.vb`
- `Business\SAIF.Business.Claim.EAIP\Reimbursement\clsBalanceDCBS.vb`
- `Business\SAIF.Business.Claim.EAIP\Targeting\clsTargeting.vb`
- `Business\SAIF.Business.Claim.EAIP\Search\clsSearchCriteria.vb`
- `Business\SAIF.Business.Claim.EAIP\mdlCodeTables.vb`
