Skip to content

Business rules

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.
Source src/SAIF.Framework.Validation/ClassCodeValidator.vb:64

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.
Source src/SAIF.Framework.Validation/ClassCodeValidator.vb:118

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.
Source src/SAIF.PremiumAudit.Batch/AuditProcessor.vb:377

BR-007 Rejected audits stay correctable

Field Value
Statement 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.
Source src/SAIF.PremiumAudit.Batch/AuditProcessor.vb:198

Notes

  • 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.

Sources

  • src/SAIF.PremiumAudit.Batch/Program.vb
  • src/SAIF.PremiumAudit.Batch/AuditProcessor.vb
  • src/SAIF.PremiumAudit.Batch/App.config
  • src/SAIF.Framework.Validation/ClassCodeValidator.vb