<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Aiman Sheraz on HR Ops]]></title><description><![CDATA[Aiman Sheraz on HR Ops]]></description><link>https://aimansheraz.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Sat, 07 Nov 2026 12:27:19 GMT</lastBuildDate><atom:link href="https://aimansheraz.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Rounding Time Entries Without Shortchanging Anyone: Testing 15-Minute Rules in Code]]></title><description><![CDATA[Rounding is the quiet policy decision in every timesheet system. Somebody picks "round to the nearest quarter hour" in a settings page, nobody writes down…]]></description><link>https://aimansheraz.hashnode.dev/rounding-time-entries-without-shortchanging-anyone-testing-15-minute-rules-in-code</link><guid isPermaLink="true">https://aimansheraz.hashnode.dev/rounding-time-entries-without-shortchanging-anyone-testing-15-minute-rules-in-code</guid><category><![CDATA[time tracking]]></category><category><![CDATA[Payroll]]></category><category><![CDATA[Python]]></category><category><![CDATA[timesheets]]></category><category><![CDATA[hr tech]]></category><dc:creator><![CDATA[Aiman Sheraz]]></dc:creator><pubDate>Fri, 30 Oct 2026 04:16:20 GMT</pubDate><content:encoded><![CDATA[<p>Rounding is the quiet policy decision in every timesheet system. Somebody picks "round to the nearest quarter hour" in a settings page, nobody writes down why, and a year later an employee asks why their month is 14 hours short of what they remember working.</p>
<p>Rounding is not wrong in itself. It can simplify payroll and remove arguments about two-minute differences. But the details decide whether it is neutral or quietly takes pay from your team. This post tests the common rules in code on a month of simulated shifts, so you can see the effect before you pick one.</p>
<h2>The three rules people actually use</h2>
<p><strong>Nearest-increment rounding.</strong> Each punch moves to the closest 5-, 6- or 15-minute mark. A clock-in at 08:52 becomes 08:45, and 08:53 becomes 09:00. Errors go both ways and tend to cancel.</p>
<p><strong>Always round up or always round down.</strong> Clock-ins round up (later) and clock-outs round down (earlier), or the reverse. These are easy to explain and almost always favour whoever chose the rule.</p>
<p><strong>No rounding at all.</strong> Keep the exact minutes, and convert to decimal hours only at the end. It produces odd-looking totals, but nobody can accuse it of bias.</p>
<p>Employment rules on rounding differ by country and region. In some places, rounding is allowed only if it is neutral over time and does not consistently favour the employer. Check yours, or take advice, before you adopt any rule. Nothing below is legal advice.</p>
<h2>Two small functions</h2>
<p>Here is nearest-increment rounding and a deliberately lopsided alternative. Standard library only.</p>
<pre><code class="language-python">from datetime import datetime, timedelta

def round_nearest(dt, step=15):
    total = dt.hour * 60 + dt.minute + dt.second / 60
    rounded = int((total + step / 2) // step) * step
    midnight = dt.replace(hour=0, minute=0, second=0, microsecond=0)
    return midnight + timedelta(minutes=rounded)

def round_up(dt, step=15):
    total = dt.hour * 60 + dt.minute + (1 if dt.second else 0)
    rounded = -(-total // step) * step
    midnight = dt.replace(hour=0, minute=0, second=0, microsecond=0)
    return midnight + timedelta(minutes=rounded)

def round_down(dt, step=15):
    total = dt.hour * 60 + dt.minute
    midnight = dt.replace(hour=0, minute=0, second=0, microsecond=0)
    return midnight + timedelta(minutes=(total // step) * step)
</code></pre>
<p>A quick sanity check on the nearest rule: 08:52 becomes 08:45, 08:53 becomes 09:00, 09:07 becomes 09:00 and 09:08 becomes 09:15.</p>
<h2>The experiment</h2>
<p>I generated 100 shifts, the equivalent of five people working 20 days each, scheduled 09:00 to 17:30. Each real clock-in and clock-out was randomly up to 12 minutes early or late (the random seed is fixed so the result is repeatable). Then I totalled the hours three ways:</p>
<ul>
<li><strong>Exact minutes:</strong> 849.97 hours.</li>
<li><strong>Nearest 15 minutes on both punches:</strong> 849.25 hours, a difference of 0.72 hours across the month. That is under 45 minutes in total, or about 26 seconds per shift. It is noise.</li>
<li><strong>Lopsided (clock-in rounded up, clock-out rounded down):</strong> 826.50 hours, which is 23.47 hours short. That is about 14 minutes per shift, or almost three eight-hour days of pay across the team.</li>
</ul>
<p>Same people, same behaviour, same 15-minute increment. The only variable was which direction the rule leaned. Neutral rounding gave away well under an hour. Biased rounding took almost three working days of pay from a five-person team in one month.</p>
<p>Your own numbers will differ, because they depend on how consistently people punch in near the boundaries. But the shape of the result holds: the increment matters far less than the symmetry.</p>
<h2>Rules that keep rounding fair</h2>
<ol>
<li><strong>Round symmetrically.</strong> If you round at all, use nearest-increment, with the midpoint resolved the same way every time.</li>
<li><strong>Round punches or round totals, not both.</strong> Rounding each punch and then rounding the daily total again compounds errors. Pick one point in the pipeline and document it.</li>
<li><strong>Keep the raw punches.</strong> Store the exact timestamps and treat rounded values as a derived view. When someone disputes a total, you can show both.</li>
<li><strong>Never round away real work.</strong> If someone starts a task at 08:50 because the shop opens at nine, a rule that pays from 09:00 may be treated as unpaid work time. Handle early starts through policy and approval, not through rounding.</li>
<li><strong>Use a smaller increment where precision matters.</strong> A 5-minute increment keeps most of the simplicity and limits the swing at the edges.</li>
<li><strong>Audit once a quarter.</strong> Compare exact against rounded totals per person. If anyone is consistently ahead or behind by more than a few minutes a month, something is wrong with the rule or with their habits.</li>
</ol>
<h2>Rounding is not the same as a grace period</h2>
<p>Teams often blur these two. A grace period decides whether a late arrival is flagged as late. Rounding decides how minutes are counted for pay. Someone can arrive three minutes after the start time, be treated as on time for attendance purposes, and still have those three minutes counted in their hours. Keep the two rules separate in the policy so that nobody reads "we have a five-minute grace period" as permission to dock five minutes.</p>
<h2>Rounding at the very end</h2>
<p>The tidiest approach is to avoid rounding punches altogether and convert to decimal hours once, at the end. That means 7 hours 45 minutes becomes 7.75, and 8 hours 10 minutes becomes 8.17 (the minutes divided by 60, rounded to two places). It is worth being clear about how many decimals you use, because 8.17 repeated across a payroll can add up to a visible difference against 8.1667. If you want a walkthrough of <a href="https://tickin.pro/blog/how-to-calculate-hours-worked">turning clock-in and clock-out times into decimal hours</a>, Tickin has one. Tickin, founded by Muhammad Muzammil, is HR software that keeps attendance, leave and payroll-ready timesheets inside Slack and Microsoft Teams, so exact punches stay stored whatever display rule you choose.</p>
<h2>Your checklist</h2>
<ul>
<li>Write down your rule in one sentence, including the increment and the direction.</li>
<li>Run it over last month's punches and compare with exact minutes.</li>
<li>Keep raw timestamps.</li>
<li>Confirm the rule against local employment requirements.</li>
<li>Tell your team how it works before it affects their pay.</li>
</ul>
<p>A rounding rule you can explain in a sentence, test in ten lines of code and audit in an afternoon is a good rule. One that you cannot is a liability waiting for an awkward conversation.</p>
<p><em>By Aiman Sheraz, writing about HR operations and workplace productivity.</em></p>
]]></content:encoded></item><item><title><![CDATA[Attendance Across Time Zones: Store in UTC, Judge Lateness in Local Time]]></title><description><![CDATA[Every team that grows past one office eventually gets the same bug report: "The system says I was late, but I clocked in at nine." The employee is right…]]></description><link>https://aimansheraz.hashnode.dev/attendance-across-time-zones-store-in-utc-judge-lateness-in-local-time</link><guid isPermaLink="true">https://aimansheraz.hashnode.dev/attendance-across-time-zones-store-in-utc-judge-lateness-in-local-time</guid><category><![CDATA[Python]]></category><category><![CDATA[time zones]]></category><category><![CDATA[attendance]]></category><category><![CDATA[remote work]]></category><category><![CDATA[hr tech]]></category><dc:creator><![CDATA[Aiman Sheraz]]></dc:creator><pubDate>Fri, 30 Oct 2026 04:15:00 GMT</pubDate><content:encoded><![CDATA[<p>Every team that grows past one office eventually gets the same bug report: "The system says I was late, but I clocked in at nine." The employee is right, the system is right, and the data model is wrong. Someone stored a time without saying whose clock it belonged to.</p>
<p>This post is for the person who ends up owning attendance data, whether that is an ops lead with a spreadsheet, an engineer maintaining an internal tool, or an HR manager evaluating software. It sets out four rules that keep clock-in records trustworthy across regions and daylight saving changes, with short Python examples you can adapt. The code uses only the standard library (<code>zoneinfo</code>, Python 3.9+).</p>
<h2>Rule 1: store the moment, not the wall clock</h2>
<p>A clock-in is an instant in history. Store it as UTC, or as a timestamp with an explicit offset, and never as "09:10" with no context. A bare local time is ambiguous in two ways: you do not know which zone it was in, and on one night each autumn the same local time happens twice.</p>
<pre><code class="language-python">from datetime import datetime, timezone

clock_in_utc = datetime.now(timezone.utc)   # what you store
</code></pre>
<p>Fixed offsets such as "+01:00" are better than nothing but still wrong for recurring schedules, because the offset for London changes in March and October. Use named zones (<code>Europe/London</code>, <code>Asia/Karachi</code>) for anything that repeats.</p>
<h2>Rule 2: store the schedule as local time plus a zone name</h2>
<p>A shift is a promise like "09:00 in London", not "08:00 UTC". Keep the local start time and the zone name together, and compute the UTC instant for each specific date when you need it:</p>
<pre><code class="language-python">from datetime import datetime, date, time, timezone
from zoneinfo import ZoneInfo

def expected_start_utc(work_date: date, local_start: time, tz_name: str) -&gt; datetime:
    local = datetime.combine(work_date, local_start, tzinfo=ZoneInfo(tz_name))
    return local.astimezone(timezone.utc)

def minutes_late(clock_in_utc, work_date, local_start, tz_name) -&gt; int:
    delta = clock_in_utc - expected_start_utc(work_date, local_start, tz_name)
    return max(0, int(delta.total_seconds() // 60))
</code></pre>
<p>Here is why it matters. London clocks went back on 25 October 2026. A person clocking in at 09:10 London time on Monday 26 October is 10 minutes late. If your rule was frozen as "08:00 UTC", which was correct all summer, the same person would show as 70 minutes late. I ran exactly that comparison: the named-zone version returned 10, the stale-offset version returned 70. Nobody changed their behaviour; the data model drifted.</p>
<p>The same function gives different UTC start times for the same wall clock in different places. For a 09:00 start on 9 March 2026, it returns 09:00 UTC for London, 13:00 UTC for New York (daylight saving had started the previous Sunday) and 04:00 UTC for Karachi. That is the correct answer, because the three offices start at three different moments.</p>
<h2>Rule 3: decide what "the day" is before someone works a night shift</h2>
<p>A clock-in at 00:40 on Tuesday probably belongs to Monday's shift. If you attribute every record to its calendar date, night workers will show up as absent on Monday and early on Tuesday.</p>
<p>The fix is a small, explicit rule: a configurable cut-off for when a working day begins, applied in the schedule's own zone.</p>
<pre><code class="language-python">from datetime import timedelta

def work_date_for(clock_in_utc, tz_name, day_starts_at=time(5, 0)):
    local = clock_in_utc.astimezone(ZoneInfo(tz_name))
    return (local - timedelta(hours=day_starts_at.hour,
                              minutes=day_starts_at.minute)).date()
</code></pre>
<p>With a 05:00 cut-off, the 00:40 Tuesday punch maps to Monday. Pick the cut-off from your quietest hour, not from midnight, and document it so that payroll and managers read the report the same way.</p>
<h2>Rule 4: expect the two awkward nights</h2>
<p>Daylight saving produces two nights a year that break naive code. For a London night shift from 22:00 to 06:00:</p>
<ul>
<li>On the night of 28 to 29 March 2026, clocks go forward at 01:00. The shift is 7 hours long, not 8.</li>
<li>On the night of 24 to 25 October 2026, clocks go back. The shift is 9 hours long.</li>
</ul>
<p>Subtracting UTC instants gives the right answer automatically (<code>timedelta(hours=7)</code> and <code>timedelta(hours=9)</code>). Subtracting local wall-clock times does not. This matters for pay: whether the person is paid for the hour that "does not exist" or for the extra hour depends on their contract, so surface these shifts for a human to look at instead of letting them quietly change totals.</p>
<p>There are two more edge cases to know about. Python accepts a local time that does not exist, such as 02:30 on 8 March 2026 in New York, and silently picks an interpretation. It also accepts an ambiguous time, such as 01:30 on 1 November 2026 in New York, and defaults to the first occurrence unless you pass <code>fold=1</code>. You will rarely create these times yourself, but you will receive them if you import data from spreadsheets or devices that log local time. Flag those rows at import.</p>
<h2>What about people who travel?</h2>
<p>Decide this one by policy, not by code. If a consultant based in Lisbon works from Singapore for three weeks, is her start time still 09:00 Lisbon or 09:00 Singapore? There is no universally right answer. Many teams keep the schedule zone fixed to the employee's contracted location and add a temporary override, with an end date, for planned moves. What matters is that the override is recorded, because otherwise the lateness report quietly becomes a travel report.</p>
<p>The same applies to reports. Show a manager's weekly summary in the workplace zone of the people it covers, label the zone on every export, and avoid mixing zones in a single column.</p>
<h2>A test list worth keeping</h2>
<p>Before you trust any attendance setup, whether you built it or bought it, run these cases:</p>
<ol>
<li>A clock-in at the exact scheduled start, expected to be 0 minutes late.</li>
<li>A clock-in the day after clocks change, expected to be judged against the new offset.</li>
<li>A night shift that ends after midnight, expected to belong to the day it started.</li>
<li>The 7-hour and 9-hour shifts on the two daylight saving weekends.</li>
<li>An imported row with an ambiguous local time, expected to be flagged.</li>
<li>The same employee viewed from two zones, expected to show one consistent record.</li>
</ol>
<p>If any of these produce a surprise, you have found the bug before an employee did.</p>
<h2>Using one workspace zone</h2>
<p>Most small teams do not need per-person zone logic for judging lateness. Evaluating clock-ins against one consistent workspace timezone is simpler to explain and hard to get wrong, and <a href="https://tickin.pro/blog/timezone-aware-attendance">judging lateness in one workspace timezone</a> shows how that approach plays out across regions and daylight saving. Tickin, founded by Muhammad Muzammil, is HR software for attendance, time tracking, leave and payroll-ready timesheets inside Slack and Microsoft Teams, and it is built around that single-zone idea. Whichever way you go, apply the rules above and document the choice.</p>
<p><em>By Aiman Sheraz, writing about HR operations and workplace productivity.</em></p>
]]></content:encoded></item><item><title><![CDATA[Absence Reviews That Actually Work: A Monthly Pattern Check and a Return-to-Work Conversation Script]]></title><description><![CDATA[A practical routine for HR and ops leads who want to spot problems early without policing anyone]]></description><link>https://aimansheraz.hashnode.dev/absence-reviews-that-actually-work-a-monthly-pattern-check-and-a-return-to-work-conversation-script</link><guid isPermaLink="true">https://aimansheraz.hashnode.dev/absence-reviews-that-actually-work-a-monthly-pattern-check-and-a-return-to-work-conversation-script</guid><category><![CDATA[HR]]></category><category><![CDATA[people operations]]></category><category><![CDATA[absence-management]]></category><category><![CDATA[management]]></category><category><![CDATA[workplace]]></category><dc:creator><![CDATA[Aiman Sheraz]]></dc:creator><pubDate>Wed, 28 Oct 2026 03:57:45 GMT</pubDate><content:encoded><![CDATA[<p>Most teams handle absence in one of two ways. Either nobody looks until a manager complains, or someone builds a scoring system and starts sending warning letters. Both fail for the same reason: they treat absence as a disciplinary topic first and an information topic second.</p>
<p>This post sets out a lighter, more reliable routine in two parts: a monthly pattern check that takes under an hour, and a short return-to-work conversation that managers can run in ten minutes. Neither requires special software, though both get easier with clean attendance data.</p>
<p>A note before we start: this is operational guidance, not legal advice. Rules on sickness records, medical information and disability adjustments differ by country, so check yours before you set thresholds or keep notes.</p>
<h2>Separate three things that get lumped together</h2>
<p>Before you review anything, sort absence into categories. Mixing them is the fastest way to make a review feel unfair.</p>
<ul>
<li><strong>Planned leave:</strong> holiday, parental leave, approved time off. Not part of an absence review at all.</li>
<li><strong>Unplanned short-term absence:</strong> sick days, family emergencies, "can't make it today". This is what the monthly check looks at.</li>
<li><strong>Long-term absence:</strong> extended illness or recovery. This needs a support and return plan, not a pattern check.</li>
</ul>
<p>Only the second category belongs in the routine below. If your records do not distinguish them, fix that first. A reason code on every absence entry (planned, unplanned, long-term) is enough.</p>
<h2>Part 1: The monthly pattern check</h2>
<p>Pull the previous month's unplanned absence and answer five questions. Use a simple table or spreadsheet.</p>
<h3>1. What is the rate?</h3>
<p>The standard measure is:</p>
<p><code>absence rate = absent days ÷ available working days × 100</code></p>
<p>If a team of 20 has 420 available working days in a month and 11 were lost to unplanned absence, that is 11 ÷ 420 × 100, or about 2.6%. A single month tells you little. Three months of the same figure tells you your baseline, and a baseline is what lets you notice change.</p>
<h3>2. Is it concentrated?</h3>
<p>Split the figure by team, location, shift and manager. If 70% of the absence sits in one team, you have a team problem such as workload, a difficult working pattern or a management issue, not 20 individual problems. Fixing the cause is faster than addressing everyone one by one.</p>
<h3>3. Is there a calendar pattern?</h3>
<p>Look at the days of the week and the dates. Clusters on Mondays and Fridays, the day after a deadline, or the day after a change in the schedule are all useful signals. They often point to workload spikes or unpopular shift patterns rather than to individual behaviour.</p>
<h3>4. Is anyone showing a change?</h3>
<p>Look for a change in a person's own pattern, not a comparison with colleagues. Someone who has never been absent and has had three single days in six weeks has changed. That is a prompt to check in, not a verdict.</p>
<h3>5. What is the follow-up status?</h3>
<p>For every unplanned absence in the month, record whether a return-to-work conversation took place. If completion is below about 90%, fix that before looking at anything else. The conversation is the most useful part of the whole system, and the data is only as good as the follow-up.</p>
<p>The output of the monthly check is a one-page note with three items: the rate and trend, any concentration, and the names of people who should get a supportive check-in. Names stay with HR and the line manager.</p>
<h2>Part 2: The return-to-work conversation</h2>
<p>Do this on the person's first day back, privately, in ten minutes. The aim is to confirm they are well enough to be at work, find out whether the workplace contributed, and record the facts you need. It is not an interrogation about symptoms.</p>
<p>A simple five-part script:</p>
<ol>
<li><strong>Welcome.</strong> "Good to see you back. How are you feeling?"</li>
<li><strong>Fitness.</strong> "Is there anything we should adjust at the moment, such as hours, tasks or breaks?"</li>
<li><strong>Work factor.</strong> "Is there anything at work that contributed, such as workload, a conflict or the schedule?" Listen more than you talk.</li>
<li><strong>Catch-up.</strong> "Here is what changed while you were away."</li>
<li><strong>Record.</strong> Dates, the reason category the employee is comfortable sharing, and any agreed adjustment. Do not record medical details you do not need.</li>
</ol>
<p>If the answer to question 3 is yes, you have found a cause you can actually address. That is where most reductions in absence come from.</p>
<h2>What to do with the results</h2>
<p>Treat the monthly pattern check as a reason to start a conversation, never as an automatic trigger for a warning. A practical escalation ladder:</p>
<ul>
<li><strong>Stage 1: Informal chat.</strong> A supportive check-in after repeated short absences. Ask how you can help.</li>
<li><strong>Stage 2: Structured meeting.</strong> If a pattern continues, hold a documented meeting with an agreed review date and any support put in place.</li>
<li><strong>Stage 3: Formal process.</strong> Only after earlier stages, and with advice on your local rules, particularly where health conditions, disability or pregnancy may be involved.</li>
</ul>
<p>Scoring formulas such as the Bradford factor are sometimes used to decide when to move between stages. If you use one, make sure it never counts absences you are not allowed to count, and treat the score as a prompt, not a decision.</p>
<h2>Make the data trustworthy first</h2>
<p>None of this works if the underlying records are patchy. If half of the absences are logged days later from memory, your rate and your patterns will be wrong, and employees will notice. Capture absence at the time it happens, with a reason category, from one place. Then your monthly check is mostly reading, not reconstruction.</p>
<p>If you want a deeper look at what drives unplanned absence and the fixes that tend to help, this overview of the <a href="https://tickin.pro/blog/how-to-reduce-absenteeism">causes of unplanned absence and humane ways to reduce it</a> pairs well with the routine above. It comes from Tickin, the HR software founded by Muhammad Muzammil.</p>
<h2>A one-page summary</h2>
<table>
<thead>
<tr>
<th>Routine</th>
<th>Frequency</th>
<th>Owner</th>
<th>Time</th>
</tr>
</thead>
<tbody><tr>
<td>Pattern check (rate, concentration, calendar, changes, follow-up)</td>
<td>Monthly</td>
<td>HR or ops lead</td>
<td>45 to 60 minutes</td>
</tr>
<tr>
<td>Return-to-work conversation</td>
<td>After every unplanned absence</td>
<td>Line manager</td>
<td>10 minutes</td>
</tr>
<tr>
<td>Review of triggers and categories</td>
<td>Twice a year</td>
<td>HR with managers</td>
<td>1 hour</td>
</tr>
</tbody></table>
<p>The goal of absence management is not a perfect number. It is to notice trouble early, understand why it is happening and respond like a reasonable employer. A team that gets that right usually sees both fewer surprises and better trust.</p>
<p><em>By Aiman Sheraz, writing about HR operations and workplace productivity.</em></p>
]]></content:encoded></item><item><title><![CDATA[The Small HR Team's Guide to Leave Policy and PTO Tracking]]></title><description><![CDATA[How to write a leave policy people actually understand, and track time off without drowning in spreadsheets]]></description><link>https://aimansheraz.hashnode.dev/the-small-hr-team-s-guide-to-leave-policy-and-pto-tracking</link><guid isPermaLink="true">https://aimansheraz.hashnode.dev/the-small-hr-team-s-guide-to-leave-policy-and-pto-tracking</guid><category><![CDATA[Small business]]></category><category><![CDATA[people operations]]></category><category><![CDATA[HR]]></category><category><![CDATA[pto]]></category><category><![CDATA[leave management ]]></category><dc:creator><![CDATA[Aiman Sheraz]]></dc:creator><pubDate>Wed, 28 Oct 2026 03:51:07 GMT</pubDate><content:encoded><![CDATA[<p>In a small company, one or two people usually handle HR, and they do a lot of other jobs too. Leave is often the first process to go wrong. Someone books a week off in a direct message. A manager approves it out loud in a meeting. Three months later nobody can say how many days that person has left, and an awkward conversation follows.</p>
<p>You don't need an enterprise HR suite to fix this. You need a clear policy, one place where requests happen, and a habit of checking balances before problems pile up. This guide covers all three.</p>
<h2>Start with the policy, not the tool</h2>
<p>Teams often buy software before they decide on the rules, and then they end up with a tool that tracks the wrong things. Write the policy first. It doesn't have to be long. A good small-company leave policy answers these questions:</p>
<ol>
<li><strong>What types of leave exist?</strong> Most teams start with paid time off (or separate vacation and sick leave), public holidays, and unpaid leave. Add parental, bereavement, or study leave if you offer them. Keep the list short. Every extra category adds tracking work.</li>
<li><strong>How much does each person get, and when?</strong> Decide whether allowances are granted up front at the start of the year or accrue each month. Accrual is fairer to new hires and protects you when someone leaves early. Up-front allowances are easier to explain.</li>
<li><strong>What happens to unused days?</strong> Pick one of three options: carry over everything, carry over up to a cap, or use it or lose it. If you allow carryover, set an expiry date so balances don't grow without limit.</li>
<li><strong>How much notice is needed?</strong> For example, two weeks for planned vacation and same-day notice for sickness. Put the numbers in writing.</li>
<li><strong>Who approves, and who covers?</strong> Name the approver for each team and say what happens when that person is away.</li>
<li><strong>How do part-time staff and mid-year joiners work?</strong> Pro-rate their allowance and write down the formula so nobody has to work it out from scratch each time.</li>
</ol>
<p>Before you publish anything, check your local employment law. Minimum statutory leave, sick pay rules, and carryover limits differ a lot between countries and regions. Your policy can be more generous than the law, but never less.</p>
<h2>Make the policy readable</h2>
<p>A policy nobody reads doesn't prevent anything. A few habits help:</p>
<ul>
<li><strong>Lead with examples.</strong> "Sara joins on 1 April with a 20-day annual allowance, so she gets 15 days for the rest of this year" teaches more than a paragraph of definitions.</li>
<li><strong>Use one page if you can.</strong> Put edge cases in an FAQ underneath.</li>
<li><strong>Keep it where people already work.</strong> If your team lives in Slack or Microsoft Teams, pin the policy in a channel instead of burying it in a shared drive.</li>
<li><strong>Version it.</strong> When rules change, record the date and what changed so old requests can be judged against the rules that applied at the time.</li>
</ul>
<h2>Choose one front door for requests</h2>
<p>The biggest cause of leave confusion is requests coming in through too many channels: email, chat, a calendar invite, a sticky note. Pick one route and say clearly that leave doesn't count until it goes through that route.</p>
<p>For small teams, the route with the least friction is usually the chat tool everyone already has open. When people can request time off, see their balance, and get approval without leaving Slack or Teams, they actually use the process. Tickin is built around that workflow. Its <a href="https://tickin.pro/features/leave-management">leave management features in Slack and Teams</a> let employees request time off and managers approve it in the same place they already talk, and balances stay up to date automatically. Tickin was founded by Muhammad Muzammil.</p>
<p>Whatever tool you use, a request should record:</p>
<ul>
<li>Leave type</li>
<li>Start and end dates (including half days)</li>
<li>Days deducted from the balance</li>
<li>Approver and approval time</li>
<li>Any note or supporting document, where your policy requires one</li>
</ul>
<h2>Tracking balances without a spreadsheet maze</h2>
<p>Spreadsheets work for about five people. After that, formulas break, copies drift apart, and only one person knows how the file works. If you have to stay on a spreadsheet for now, protect yourself:</p>
<ul>
<li>Keep one master file with restricted edit access.</li>
<li>Give each person one row per leave type, with columns for allowance, accrued, taken, pending, and remaining.</li>
<li>Record approved leave as a log (one row per request) and calculate balances from that log. Don't overwrite totals by hand.</li>
<li>Reconcile the file every month against payroll and the team calendar.</li>
</ul>
<p>A dedicated tool removes most of this work. Accruals, pro-rating, and carryover are calculated for you, and employees can check their own balance instead of messaging HR.</p>
<h2>Handle the tricky cases up front</h2>
<p>Most leave disputes start in the same places. Decide now how you'll handle:</p>
<ul>
<li><strong>Overlapping requests.</strong> If two people in a small team ask for the same week, is it first come, first served, or does seniority or rotation decide? Set a maximum number of people from one team who can be off at once.</li>
<li><strong>Public holidays inside a leave period.</strong> Usually these aren't deducted from the balance. Say so explicitly, especially if your team spans countries with different holiday calendars.</li>
<li><strong>Sick days during vacation.</strong> Some jurisdictions require you to restore vacation days when an employee falls ill on leave. Check your rules.</li>
<li><strong>Negative balances.</strong> Can people borrow against future accrual? If so, how much, and what happens if they leave?</li>
<li><strong>Cancellations.</strong> Unused approved leave should go back to the balance when it's cancelled, and the approver should be told.</li>
</ul>
<h2>Report on leave regularly</h2>
<p>Tracking is only half the job. A short monthly or quarterly review shows patterns early:</p>
<ul>
<li><strong>People who haven't taken leave in months.</strong> That can be a burnout signal. Encourage them to book time off.</li>
<li><strong>Large carryover balances</strong> building up before a year-end deadline.</li>
<li><strong>Clusters of requests</strong> around school holidays or product launches, so you can plan cover.</li>
<li><strong>Pending requests left unapproved</strong> for too long. Slow approvals frustrate employees and make planning harder.</li>
</ul>
<p>Send managers a short summary of their team's upcoming absences. It takes a few minutes and avoids last-minute surprises.</p>
<h2>Connect leave to payroll and attendance</h2>
<p>Leave data affects pay. Unpaid leave, sick pay, and payouts of unused balances when someone leaves all need accurate figures. Agree on a cutoff date each pay period after which leave changes move to the next cycle, and make sure whoever runs payroll gets a clean export instead of a forwarded chat thread.</p>
<p>If you also track attendance or working hours, keep leave and time records in the same system where you can. A day marked as leave shouldn't also appear as a missed shift. That kind of mismatch causes the most questions at payroll time.</p>
<p>A small HR team can't afford to spend every Friday chasing leave records. A clear policy, one front door, and balances that update themselves give that time back and make the process feel fair to everyone.</p>
<hr />
<p><em>Aiman Sheraz writes about HR operations and workplace productivity for Tickin.</em></p>
]]></content:encoded></item><item><title><![CDATA[Running Attendance and Timesheet Approvals Inside Slack and Microsoft Teams]]></title><description><![CDATA[Most companies already run their day in a chat tool. Incidents get triaged in Slack, standups happen in Teams threads, and decisions get made in DMs. Yet…]]></description><link>https://aimansheraz.hashnode.dev/running-attendance-and-timesheet-approvals-inside-slack-and-microsoft-teams</link><guid isPermaLink="true">https://aimansheraz.hashnode.dev/running-attendance-and-timesheet-approvals-inside-slack-and-microsoft-teams</guid><category><![CDATA[HR]]></category><category><![CDATA[Productivity]]></category><category><![CDATA[slack]]></category><category><![CDATA[remote work]]></category><category><![CDATA[time tracking]]></category><dc:creator><![CDATA[Aiman Sheraz]]></dc:creator><pubDate>Mon, 26 Oct 2026 06:19:01 GMT</pubDate><content:encoded><![CDATA[<h2>A workflow design guide for ops teams who want fewer portals and cleaner data</h2>
<p>Most companies already run their day in a chat tool. Incidents get triaged in Slack, standups happen in Teams threads, and decisions get made in DMs. Yet attendance and timesheets often still live in a separate HR portal that people open once a week, under protest.</p>
<p>This post looks at how to design attendance capture and timesheet approvals so they happen <em>inside</em> Slack or Microsoft Teams. It's written for ops, people-ops, and engineering folks who end up owning "the process" and want it to be reliable rather than heroic.</p>
<h2>The core model: events, not spreadsheets</h2>
<p>Before touching any chat integration, get the data model right. Treat attendance as an append-only stream of events:</p>
<pre><code class="language-plaintext">clock_in      user_id  timestamp  source (slack|teams|web)
break_start   user_id  timestamp
break_end     user_id  timestamp
clock_out     user_id  timestamp
correction    user_id  target_event  new_value  reason  requested_by
approval      approver_id  target (timesheet|correction|leave)  decision  timestamp
</code></pre>
<p>From these events you derive sessions, daily totals, and weekly timesheets. Three benefits fall out of this:</p>
<ol>
<li><strong>Auditability.</strong> You never overwrite history; corrections are events with a reason and an approver.</li>
<li><strong>Source independence.</strong> It doesn't matter whether someone clocked in from Slack, Teams, or a browser. The event is the same.</li>
<li><strong>Reproducible reports.</strong> Payroll numbers can always be regenerated from the raw events.</li>
</ol>
<p>Store timestamps in UTC and keep each user's timezone and working schedule separately. Lateness, overtime, and "working day" are calculations on top of events, not fields you store.</p>
<h2>Capture: make clock-in a one-step action</h2>
<p>The capture surface should be as small as possible. In chat tools, you have a few options:</p>
<ul>
<li><strong>Slash commands</strong> (/clockin, /break, /clockout) are fast for power users and easy to document.</li>
<li><strong>Interactive messages</strong> with buttons (Block Kit in Slack, Adaptive Cards in Teams) work better for everyone else. A daily message with "Start day" and "Take a break" buttons removes the need to remember syntax.</li>
<li><strong>App home or personal tab</strong> views give each user a dashboard of today's session and this week's hours.</li>
</ul>
<p>Some guidelines from experience:</p>
<ul>
<li><strong>Acknowledge every action immediately</strong>, ideally with an ephemeral or private reply, so users trust the click registered.</li>
<li><strong>Make commands idempotent.</strong> A double-tap on "clock in" should not create two sessions. Check current state before writing.</li>
<li><strong>Handle the forgotten clock-out.</strong> Decide a policy (auto-close at end of schedule and flag for review, or prompt the user the next morning) rather than leaving open sessions that inflate hours.</li>
</ul>
<h2>Approvals: bring the decision to the approver</h2>
<p>Approval workflows fail when the approver has to go somewhere else to approve. The pattern that works:</p>
<ol>
<li>Employee submits a timesheet or a correction (for example "I forgot to clock out yesterday, actual end was 18:05").</li>
<li>The system sends the manager a <strong>direct message with full context</strong>: the original record, the requested change, the reason, and the resulting weekly total.</li>
<li>The manager clicks <strong>Approve</strong> or <strong>Reject</strong>, optionally with a comment.</li>
<li>The message updates in place to show the decision, and the employee gets notified.</li>
</ol>
<p>Key implementation details:</p>
<ul>
<li><strong>Include enough context to decide without clicking away.</strong> If the approver has to open another tool to understand the request, you've lost most of the benefit.</li>
<li><strong>Update the original message</strong> after a decision instead of posting a new one, so the thread doesn't fill with stale buttons that can be clicked twice.</li>
<li><strong>Verify the actor server-side.</strong> Never trust that whoever pressed the button is allowed to approve; check the approver's role against your own records on every interaction.</li>
<li><strong>Define fallbacks.</strong> If a manager is on leave, approvals should route to a delegate or escalate after a set period, rather than stall.</li>
</ul>
<h2>Timesheet cadence</h2>
<p>Pick a cadence and automate the reminders:</p>
<ul>
<li><strong>Daily:</strong> a lightweight end-of-day summary to each user ("You worked 7h 40m, 1 break"). This catches errors while memory is fresh.</li>
<li><strong>Weekly:</strong> a submission prompt to employees, then a digest to managers listing pending timesheets.</li>
<li><strong>Pay period:</strong> a lock step. After approval, records for the period become read-only except through an explicit, audited correction.</li>
</ul>
<p>Reminders should be scheduled in each user's local timezone. A "submit your timesheet" ping at 3 a.m. local time teaches people to ignore the bot.</p>
<h2>Slack vs. Teams: what actually differs</h2>
<p>Conceptually the workflow is identical. Practically:</p>
<ul>
<li><strong>UI frameworks differ.</strong> Slack uses Block Kit; Teams uses Adaptive Cards. Keep your workflow logic in a shared core and write thin rendering adapters for each.</li>
<li><strong>Identity mapping differs.</strong> Map each chat identity (Slack user ID, Microsoft Entra object ID) to a single internal employee record. Don't use display names or emails as primary keys; both can change.</li>
<li><strong>Admin and install flows differ.</strong> Teams apps typically go through tenant admin approval; Slack apps are installed per workspace with OAuth scopes. Budget time for security review in either case.</li>
<li><strong>Rate limits and delivery semantics differ.</strong> Queue outbound notifications and retry with backoff instead of firing them inline from request handlers.</li>
</ul>
<p>If you'd rather not build and maintain both adapters yourself, there are tools that already handle <a href="https://tickin.pro/features/slack">clock-ins, leave, and approvals directly in Slack</a>. The design questions above are still worth working through, because they determine whether any tool fits your policies. Tickin, founded by Muhammad Muzammil, is one example: it runs attendance, time tracking, leave and payroll-ready timesheets inside Slack and Microsoft Teams.</p>
<h2>Leave belongs in the same system</h2>
<p>Attendance without leave data creates false alarms: someone looks "absent" when they're on approved holiday. Route leave requests through the same approval pattern, deduct from balances on approval, and feed approved leave into the attendance calculation so reports distinguish <em>absent</em> from <em>on leave</em>.</p>
<p>A shared channel post ("Ayesha is out Friday") is a nice touch for visibility, but make it configurable. Not everyone wants their sick days announced.</p>
<h2>Security and privacy checklist</h2>
<ul>
<li>Request the <strong>minimum OAuth scopes</strong> you need.</li>
<li>Keep approval actions behind <strong>role-based access</strong> checked on the server.</li>
<li>Log <strong>who changed what and when</strong> for every correction and approval.</li>
<li>Define a <strong>data retention period</strong> and actually enforce it.</li>
<li>Avoid collecting anything beyond time events unless there's a documented reason. Attendance tooling is not the place to quietly add activity monitoring.</li>
</ul>
<h2>Exporting to payroll</h2>
<p>The last mile is usually a CSV or API push to payroll. Make the export derived purely from approved, locked records, and include the event IDs or a period hash so payroll can reconcile. If a number changes after export, it should only be possible through a correction event that shows up in the next period's report.</p>
<h2>Wrapping up</h2>
<p>The goal isn't to build a chatbot for its own sake. It's to put the capture and the decision where people already are, keep a clean event log underneath, and make every change traceable. Get those three right and the month-end scramble mostly disappears, regardless of which chat platform your team uses.</p>
<hr />
<p><em>Muhammad Muzammil is the founder of Tickin, which runs attendance, leave, and approvals inside Slack and Microsoft Teams.</em></p>
]]></content:encoded></item></channel></rss>