SAIF.PremiumAudit.Batch recalculates workers' compensation earned premium from
completed payroll audits and posts the resulting adjustment to the policy system.
The rules below govern which audits are eligible for a nightly run, what payroll
data is acceptable, which rate is applied, when an adjustment is material enough
to post, and how a rejected audit is recorded so that underwriting can correct it.
Payroll-level data rules are delegated to SAIF.Framework.Validation and keep that
library's VAL- identifiers; all other rules are enforced by the batch executable.
BR-001 Audited payroll must use a recognised class code¶
Field
Value
Statement
Every payroll line on an audit must carry a payroll class code that exists in the rating tables and is approved for the policy's state of coverage; an unrecognised code cannot be rated and makes the whole audit unpostable.
Trigger
Evaluated for each dbo.PolicyAuditDetail row at step 2 of the processing loop, before any premium is recalculated.
Enforcement
Delegated to SAIF.Framework.Validation rule VAL-032, applied by ClassCodeValidator.Validate against the dbo.ClassCodeValidation table.
Outcome
The audit is marked Rejected, the per-audit transaction rolls back, a dbo.PolicyAuditReject row records rule VAL-032, and the failure is written to File2 with the policy number and PolicyAuditId.
BR-002 Audited payroll amounts must be non-negative and within class limits¶
Field
Value
Statement
Reported payroll for a class code must be zero or greater and must not exceed the maximum annual payroll configured for that class code, because a negative or implausible figure would produce a premium adjustment that cannot be collected or refunded.
Trigger
Evaluated for each dbo.PolicyAuditDetail row at step 2, immediately after the class code check in BR-001 passes.
Enforcement
Delegated to SAIF.Framework.Validation rule VAL-037, applied by ClassCodeValidator.Validate using the payroll limits held in dbo.ClassCodeValidation.
Outcome
The audit is marked Rejected, the transaction rolls back, a dbo.PolicyAuditReject row records rule VAL-037, and no dbo.PremiumTransaction row is written.
BR-003 Only completed audits on or before the run's audit date are eligible¶
Field
Value
Statement
A nightly run may process only those policy audits that underwriting has marked complete with a completion date on or before the supplied audit date and that have not already been posted, so that an audit is never rated twice and an in-flight audit is never rated early.
Trigger
Evaluated once per run during step 1, when eligible audits are retrieved.
Enforcement
dbo.usp_GetPendingAudits filters dbo.PolicyAudit on Status = 'Pending' and CompletedDate <= @AuditDate, ordering by PolicyAuditId; AuditProcessor.RetrievePendingAudits passes the validated AuditDate and BatchSize arguments.
Outcome
Ineligible audits are simply not returned and remain available to a later run; the count of audits read is written to the File0 run totals.
Source
src/SAIF.PremiumAudit.Batch/AuditProcessor.vb:142
BR-004 Premium is recalculated at the rate in effect on the policy effective date¶
Field
Value
Statement
Earned premium must be recalculated using the payroll class code rate that was in effect on the policy effective date, not the rate in effect on the day the batch runs, so that an audit adjustment is consistent with the rates the policy was originally rated with.
Trigger
Evaluated for every payroll line of an audit that passed validation, at step 3 of the processing loop.
Enforcement
AuditProcessor.ResolveRate selects the dbo.PayrollClassCode row whose effective and expiration dates bracket the policy effective date from the rate table loaded during PreProcess.
Outcome
The recalculated premium is compared to the estimated premium and the difference becomes the adjustment amount; when no rate row covers the policy effective date the audit is treated as a per-record failure, rolls back, and is logged to File2.
Source
src/SAIF.PremiumAudit.Batch/AuditProcessor.vb:268
BR-005 An audit posts at most one premium adjustment transaction¶
Field
Value
Statement
Posting an audit must produce exactly one premium adjustment transaction and must move the audit out of Pending in the same action, so that a re-run or a restart can never bill a policyholder twice for the same audit.
Trigger
Evaluated at step 3, when the recalculated premium is written back to the policy system.
Enforcement
AuditProcessor.PostAdjustment inserts the dbo.PremiumTransaction row and updates dbo.PolicyAudit.Status, PostedDate, and PostedBy inside the single SQL Server transaction opened for that audit.
Outcome
The transaction commits and the audit becomes Posted, so BR-003 excludes it from every later run; if either statement fails the transaction rolls back and the audit stays Pending with no transaction row.
Source
src/SAIF.PremiumAudit.Batch/AuditProcessor.vb:341
BR-006 Immaterial adjustments are recorded but not billed¶
Field
Value
Statement
An audit whose premium difference is smaller than the materiality threshold is closed without a billable adjustment, because the cost of billing and collecting a trivial amount exceeds the amount itself.
Trigger
Evaluated at step 3 for every audit that produced a recalculated premium, after the difference to the estimated premium has been computed.
Enforcement
AuditProcessor.PostAdjustment compares the absolute adjustment amount to the MaterialityThreshold setting in App.config (default 5.00) and writes the dbo.PremiumTransaction row with a zero amount and a NoChange transaction type when the difference falls below it.
Outcome
The audit is marked Posted and appears on the File1 success report with a zero adjustment, so the run is auditable without generating a billing item.
An audit that fails validation must remain in Pending status with the failing rule identifier recorded against it, so that underwriting can correct the payroll detail and have the audit rated on a later run without manual re-entry.
Trigger
Evaluated whenever BR-001 or BR-002 records a blocking failure for an audit.
Enforcement
AuditProcessor.RecordRejection writes a dbo.PolicyAuditReject row carrying the PolicyAuditId and the failing VAL- rule identifier, then rolls back the per-audit transaction so no status change survives.
Outcome
The audit is picked up again by dbo.usp_GetPendingAudits on the next run, and the rejection appears on the File2 error report for the underwriting correction queue.
Source
src/SAIF.PremiumAudit.Batch/AuditProcessor.vb:412
BR-008 A run stops rather than post against systemically bad data¶
Field
Value
Statement
When per-audit failures exceed the configured tolerance the run must stop instead of continuing to post, because a failure rate that high indicates a bad upstream extract rather than isolated data entry errors.
Trigger
Evaluated after each per-audit failure is counted during the processing loop.
Enforcement
AuditProcessor.RunAppLogic compares the running failure count to the ErrorThreshold setting in App.config (default 25) and ends the loop when it is exceeded.
Outcome
Run totals and the last checkpoint PolicyAuditId are written to File0, the on-call notification is sent to NotificationRecipients, and the program exits with return code 5; audits already committed remain Posted and the remainder stay Pending.
Rules BR-001 and BR-002 are enforced by SAIF.Framework.Validation and keep
that library's VAL- identifiers; changing their thresholds is a change to
dbo.ClassCodeValidation data, not to this application.
MaterialityThreshold and ErrorThreshold are configuration values, so BR-006
and BR-008 can be retuned per environment without a code change.