Healthcare Worker Payroll Contract

What it does:
Automatically calculates and distributes salaries to healthcare workers based on work hours, roles, and approved shifts.

Why it matters:
Reduces payroll disputes, eliminates manual errors, and ensures transparent, timely payments for doctors, nurses, and medical staff.

How it works:

  • Admin registers healthcare workers and their roles

  • Hourly rates are defined per worker or role

  • Approved work hours are recorded on-chain

  • Payroll period is finalized by the administrator

  • Salaries are automatically calculated

  • Funds are distributed directly to workers

  • All payments are permanently auditable

      // SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

/**
 * @title HealthcareWorkerPayroll
 * @author Nam
 * @notice Automates payroll for healthcare workers
 */
contract HealthcareWorkerPayroll {

    // -------------------- ROLES --------------------

    address public admin;

    // -------------------- STRUCTS --------------------

    struct Worker {
        bool registered;
        uint256 hourlyRate; // wei per hour
        uint256 hoursWorked;
        uint256 pendingPayment;
    }

    // -------------------- STORAGE --------------------

    mapping(address => Worker) public workers;

    // -------------------- EVENTS --------------------

    event WorkerRegistered(address indexed worker, uint256 hourlyRate);
    event HoursRecorded(address indexed worker, uint256 hours);
    event PayrollCalculated(address indexed worker, uint256 amount);
    event SalaryPaid(address indexed worker, uint256 amount);

    // -------------------- MODIFIERS --------------------

    modifier onlyAdmin() {
        require(msg.sender == admin, "Not admin");
        _;
    }

    modifier onlyWorker() {
        require(workers[msg.sender].registered, "Not registered worker");
        _;
    }

    // -------------------- CONSTRUCTOR --------------------

    constructor() {
        admin = msg.sender;
    }

    // -------------------- WORKER MANAGEMENT --------------------

    /**
     * @notice Register a healthcare worker
     */
    function registerWorker(
        address _worker,
        uint256 _hourlyRate
    )
        external
        onlyAdmin
    {
        require(_worker != address(0), "Invalid address");
        require(!workers[_worker].registered, "Already registered");

        workers[_worker] = Worker({
            registered: true,
            hourlyRate: _hourlyRate,
            hoursWorked: 0,
            pendingPayment: 0
        });

        emit WorkerRegistered(_worker, _hourlyRate);
    }

    /**
     * @notice Record approved work hours
     */
    function recordHours(
        address _worker,
        uint256 _hours
    )
        external
        onlyAdmin
    {
        Worker storage w = workers[_worker];
        require(w.registered, "Worker not registered");
        require(_hours > 0, "Invalid hours");

        w.hoursWorked += _hours;
        emit HoursRecorded(_worker, _hours);
    }

    // -------------------- PAYROLL --------------------

    /**
     * @notice Calculate payroll for a worker
     */
    function calculatePayroll(address _worker)
        external
        onlyAdmin
    {
        Worker storage w = workers[_worker];
        require(w.registered, "Worker not registered");
        require(w.hoursWorked > 0, "No hours recorded");

        uint256 payment = w.hoursWorked * w.hourlyRate;
        w.pendingPayment += payment;
        w.hoursWorked = 0;

        emit PayrollCalculated(_worker, payment);
    }

    /**
     * @notice Pay salary to worker
     */
    function paySalary()
        external
        onlyWorker
    {
        Worker storage w = workers[msg.sender];
        uint256 amount = w.pendingPayment;

        require(amount > 0, "No payment available");
        require(address(this).balance >= amount, "Insufficient funds");

        w.pendingPayment = 0;
        payable(msg.sender).transfer(amount);

        emit SalaryPaid(msg.sender, amount);
    }

    // -------------------- FUNDING --------------------

    /**
     * @notice Fund payroll pool
     */
    receive() external payable {}
}