Automates payroll processing in the HRMS staging portal. Handles batch payroll operations with off-peak scheduling, cross-verification of calculations, and comprehensive audit logging. Implements rate limiting to avoid system overload. Requires hrms-auth and hrms-validator.
You handle payroll operations with extreme care. Payroll errors affect real people's livelihoods, so you validate EVERYTHING twice. You prefer processing during off-peak hours to minimize system load on the 16GB/i7-8th gen hardware.
hrms-auth — ensure active session with PAYROLL-ROLE credentialshrms-validator with module payroll — validate all payroll datahealth-check.sh — abort if resources too lowCURRENT_HOUR=$(date +%H)
OFFPEAK_START=${RATE_LIMIT_OFFPEAK_START:-22}
OFFPEAK_END=${RATE_LIMIT_OFFPEAK_END:-06}
is_offpeak() {
if [ "$CURRENT_HOUR" -ge "${OFFPEAK_START%%:*}" ] || [ "$CURRENT_HOUR" -lt "${OFFPEAK_END%%:*}" ]; then
echo "true"
else
echo "false"
fi
}
1. Validate payroll data against payroll.schema.json
2. Verify employee exists in the system
3. Check attendance records for the pay period
4. Verify no duplicate payroll run for this period
5. Load pay structure/components from policies.json
SELECTORS="$HOME/.openclaw/workspace/hrms-automation/config/selectors.json"
PAYROLL_URL=$(jq -r '.payroll.processingUrl' "$SELECTORS")
browser_navigate "${HRMS_STAGING_URL}${PAYROLL_URL}"
browser_wait_for_selector "$(jq -r '.payroll.fields.payPeriod' "$SELECTORS")" 30000
1. Select pay period from dropdown:
- Click pay period selector
- Choose the target month/year
- Wait for page to refresh (ASP.NET postback)
2. Select or search for employee:
- If individual: search by employee ID
- If batch: select "All" or specific department
3. Wait for payroll data to load
Payroll component mapping (from selectors.json):
Earnings:
.payroll.fields.basicSalary → data.basicSalary
.payroll.fields.hra → data.hra (House Rent Allowance)
.payroll.fields.conveyance → data.conveyanceAllowance
.payroll.fields.specialAllowance → data.specialAllowance
.payroll.fields.overtime → data.overtimePay
.payroll.fields.bonus → data.bonus
.payroll.fields.otherEarnings → data.otherEarnings
Deductions:
.payroll.fields.providentFund → data.providentFund
.payroll.fields.professionalTax → data.professionalTax
.payroll.fields.incomeTax → data.incomeTax (TDS)
.payroll.fields.insurance → data.healthInsurance
.payroll.fields.loanRepayment → data.loanDeduction
.payroll.fields.otherDeductions → data.otherDeductions
Calculated (verify, do not enter):
.payroll.fields.grossSalary → sum of all earnings
.payroll.fields.totalDeductions → sum of all deductions
.payroll.fields.netSalary → grossSalary - totalDeductions
For each component:
1. Wait for field to be interactable
2. Read the current/system-calculated value
3. If input data provides a value, compare and update if different
4. If input data does not provide a value, accept system calculation
5. Log every value read/entered
CRITICAL — Verify arithmetic:
1. Sum all earnings fields → compare to displayed gross salary
2. Sum all deduction fields → compare to displayed total deductions
3. Compute net = gross - deductions → compare to displayed net salary
4. Verify each component is within expected range (e.g., PF = 12% of basic)
Tolerance: ±0.01 (rounding differences only)
If ANY calculation mismatch > ±0.01:
→ Screenshot the payroll sheet
→ Log the discrepancy with expected vs actual values
→ HALT — do not submit
→ Alert user: "Payroll calculation discrepancy detected for [Employee ID]"
Only after ALL verifications pass:
1. Take pre-submission screenshot
2. Click Process/Submit button
3. Handle confirmation dialog if present (ASP.NET often shows confirm dialogs)
4. Wait for processing to complete (may take longer for batch)
5. Check for success message
6. Extract reference/transaction number
7. Take post-submission screenshot
After successful submission:
1. Navigate to pay slip generation page (if separate)
2. Generate and download pay slip PDF
3. Store in workspace/payroll/[YYYY-MM]/[EmployeeID].pdf
4. Verify PDF is valid (non-zero file size, contains expected content)
For processing an entire department or company payroll:
Batch Processing Protocol:
1. PRE-BATCH CHECKS:
- Verify off-peak hours (warn if running during peak)
- Resource check: RAM < 70%, CPU < 80%
- Estimate processing time: ~30s per employee
- Confirm with user if batch is large (>100 employees)
2. LOAD EMPLOYEE LIST:
- Read from input data or extract from HRMS
- Sort by department, then by employee ID
- Split into batches of configurable size (default: 25)
3. PROCESS EACH BATCH:
For each batch of 25 employees:
a. Check system resources (via health-check.sh)
b. If resources low → pause for 60s → recheck
c. If still low → save progress → halt → notify user
For each employee in batch:
a. Apply rate limiter: sleep ${RATE_LIMIT_MIN_INTERVAL_MS}ms
b. Run individual payroll workflow (Steps 1-7)
c. Track result: { employeeId, status, netSalary, reference, errors }
d. On error: log, continue to next employee
After batch:
a. Log batch progress: "Batch X/Y complete: N success, M failures"
b. Flush audit logs
c. Resource check
4. POST-BATCH REPORT:
Generate comprehensive report:
- Total employees processed
- Successful: count, total payout amount
- Failed: count, details, remediation suggestions
- Processing time: total, average per employee
- Resource utilization summary
Save to: workspace/reports/performance/payroll_batch_[YYYY-MM-DD].json
Available reports:
1. Monthly payroll summary (department-wise)
2. Year-to-date summary (individual or aggregate)
3. Tax deduction summary
4. Bank transfer file generation
For each report:
1. Navigate to reports section
2. Select report type and parameters
3. Generate report
4. Download and store
5. Verify file integrity
When DRY_RUN=true:
Track and report:
{
"batchId": "BATCH-2024-01-15-001",
"startTime": "2024-01-15T22:00:00Z",
"endTime": "2024-01-15T23:45:00Z",
"totalEmployees": 150,
"successful": 148,
"failed": 2,
"totalPayoutAmount": 1250000.00,
"averageProcessingTimeSec": 28.5,
"peakMemoryUsageMB": 1200,
"peakCpuUsagePct": 65,
"failedEmployees": [
{"id": "EMP042", "reason": "Calculation mismatch", "details": "..."},
{"id": "EMP099", "reason": "Session timeout during submission", "details": "..."}
]
}
| Error | Severity | Action |
|---|---|---|
| Calculation mismatch | CRITICAL | HALT, screenshot, do NOT submit, alert user |
| Duplicate payroll run | HIGH | HALT for this employee, skip, log |
| Employee not found | MEDIUM | Skip, log, continue batch |
| Session timeout | MEDIUM | Re-auth, retry current employee |
| System overload | HIGH | Pause batch, wait 60s, retry resource check |
| Network timeout | MEDIUM | Retry with exponential backoff, skip after 3 failures |
| Approval workflow pending | INFO | Log, skip (payroll needs higher authority) |
| PDF generation failed | LOW | Log, continue (can regenerate later) |