Ask any HR system to handle daily-wage workers and it will offer you the employee master. Create the worker as an employee, give them a salary structure, run monthly payroll. It works for about two weeks, and then the site does something completely ordinary and the model falls apart.
Five things a dihadi worker does that an employee never does
- 1Gets paid on a Thursday, for nine days. Not on the last of the month, and not for a calendar period.
- 2Works two sites on the same day. Half a day on Tower B, half on the boundary wall — at two different rates.
- 3Takes kharchi on Tuesday against work not yet done, and has it recovered from Thursday’s payment.
- 4Changes thekedar mid-month, while last month’s days still belong to the old one.
- 5Has no email, no login, and no interest in a self-service portal.
Every one of those is normal on a site. Every one of them is an exception in a monthly payroll engine.
The mistake: bending PayrollRun to fit
The tempting fix is to make monthly payroll accept a date range. Do not. A payroll run carries a month, a salary structure, LOP arithmetic, statutory registers keyed to a month and a payslip format built around all of it. Making it accept "9 days across two sites at two rates" means weakening every one of those assumptions for the salaried employees who still need them.
The unit that makes it work: day_fraction
The single design decision that makes daily wages tractable is choosing the right unit. Not hours. Not attendance status. A fraction of a day.
Wage = the sum of `day_fraction` × the rate stamped on that entry. Hours are sugar on top (8 hours = 1.0). Status — present, half-day, absent — is a derived label for a report, never the thing pay is computed from.
That is what allows a day total above 1.0 when someone genuinely worked two sites, and it is what stops "half day" meaning three different things in three different reports.
Stamp the rate, never look it up later
A worker has many rates over time — an effective-dated default that changes when you give them a raise, and a per-entry rate for the day two sites paid differently. The rate that matters is the one in force on the day worked, so it is written onto the attendance row when the muster is saved.
Never price a settlement from the worker’s current rate. A raise in September must not retro-price August.
The settlement then shows a weighted average rate, with the exact split frozen alongside it — so a worker asking "why is this ₹460 and not ₹500" gets a real answer instead of a recalculation.
Settle any range, and lock what you settled
Settlement runs for whatever range the site actually pays on — weekly, ten-day, half-month. Kharchi is recovered FIFO, capped so net never goes below zero. And on approval, every day consumed is locked: it cannot be edited, cannot be deleted, and cannot be picked up by another payment.
That lock is what makes the muster trustworthy afterwards. Without it, an edit three weeks later silently changes what you already paid.
What this buys you
- A wage slip per worker, with the kharchi breakdown they can actually check
- An Excel wage register with per-advance detail, for the office
- Site-wise cost reports that agree with the settlements, because both read the same rows
- Statutory registers as a report rather than a monthly project
Read more on the Daily Wages module, or about the registers this produces.