Skill Tracer
Skills › Knowledge Work Plugins › payroll-prep › timesheet_intake.md

timesheet_intake.md

118 lines · small-business/skills/payroll-prep/reference/timesheet_intake.md at 2574e29

Open on GitHub
1# Timesheet Intake
2
3Setting the period, the roster, and getting hours in from wherever they live.
4
5---
6

Timesheet Intake

Setting the period, the roster, and getting hours in from wherever they live.


Raw lines 1 to 6
7## Period setup
8
9Confirm all four before pulling anything:
11- **Period start and end** — inclusive dates
12- **Pay date** — when money actually lands
13- **Pay frequency** — weekly, biweekly, semimonthly, monthly
14- **Who is in this run** — hourly crew, salaried staff, or both
16Biweekly and semimonthly get mixed up constantly. Biweekly is every two weeks, 26 runs a year. Semimonthly is the 15th and the last day, 24 runs. If the owner says "twice a month" and the last period ran the 1st through the 14th, ask rather than assume.
18**Period boundaries matter most at month end.** A week that straddles the 31st has hours in two months for job costing but one paycheck. Keep the pay period whole and let the books sync handle the split.
20---

Period setup

Confirm all four before pulling anything:

  • Period start and end — inclusive dates
  • Pay date — when money actually lands
  • Pay frequency — weekly, biweekly, semimonthly, monthly
  • Who is in this run — hourly crew, salaried staff, or both

Biweekly and semimonthly get mixed up constantly. Biweekly is every two weeks, 26 runs a year. Semimonthly is the 15th and the last day, 24 runs. If the owner says "twice a month" and the last period ran the 1st through the 14th, ask rather than assume.

Period boundaries matter most at month end. A week that straddles the 31st has hours in two months for job costing but one paycheck. Keep the pay period whole and let the books sync handle the split.


Raw lines 7 to 21
22## Roster
24Pull the active employee list and compare it to the last run.
26| Change | What to do |
27|---|---|
28| New hire mid-period | Confirm the start date and that hours before it are excluded |
29| Termination | Confirm the final date, unused PTO payout if owed, and whether a final check has different timing under state rules |
30| On leave | Confirm paid or unpaid, and whether PTO is being drawn |
31| Someone paid last period, absent now | Flag it. This is either a termination nobody recorded or a missing timesheet |
32| Someone new with no hire record | Flag it. Never pay a person who is not on the roster |
34---

Roster

Pull the active employee list and compare it to the last run.

ChangeWhat to do
New hire mid-periodConfirm the start date and that hours before it are excluded
TerminationConfirm the final date, unused PTO payout if owed, and whether a final check has different timing under state rules
On leaveConfirm paid or unpaid, and whether PTO is being drawn
Someone paid last period, absent nowFlag it. This is either a termination nobody recorded or a missing timesheet
Someone new with no hire recordFlag it. Never pay a person who is not on the roster

Raw lines 22 to 35
36## Source: Gusto
38Before pulling anything, call `list_payroll_blockers` and translate any blockers to plain English per Step 2 of the SKILL.md — they decide whether the run stages in Gusto or ships as a run sheet.
40Then pull `list_employees` and `list_pay_schedules`. Either empty on a company that reports a headcount, or a blockers call that errors, means the source is not delivering — stop the Gusto path and say so; the run sheet path is the outcome.
42Pull, tool by tool:
44| Input | Tool | Read it like this |
45|---|---|---|
46| Hours | `list_time_records` (period start and end) | Check `source` first. `native`: shifts with clock-in, clock-out, breaks. `third_party`: timesheets; `get_time_sheet` on a timesheet's top-level id for per-day lines. `none`: no hours here, use the spreadsheet path. |
47| Leave taken | `list_time_off_requests` (period, `status: approved`) | Each approved day is paid as PTO or sick, not as worked. Pending is a flag. Notes are withheld by the tool; do not ask for them. |
48| Balances | `get_time_off_balances` | Available, accrued, used, pending per policy. Policy names need the time-off-policies scope; without it match on policy uuid. Feeds the over-balance check. |
49| Roster, rates, classifications | `list_employees` and its compensations | Employment status and the active flag are separate fields (below). |
50| Prior run | `list_payrolls`, `get_payroll` | The last processed run's per-person totals, for the comparison. |
52A missing punch the owner fills in is written with `record_time`, per Step 2 of the SKILL.md — owner-stated times only, shown first. The required parameters and the id and re-read traps are in the `record_time` row of `../../../shared/connector-call-shapes.md`; this file does not repeat them.
54Rates come from Gusto, never from the timesheet. A rate written on a paper timesheet is a note, not a record.
56---

Source: Gusto

Before pulling anything, call list_payroll_blockers and translate any blockers to plain English per Step 2 of the SKILL.md — they decide whether the run stages in Gusto or ships as a run sheet.

Then pull list_employees and list_pay_schedules. Either empty on a company that reports a headcount, or a blockers call that errors, means the source is not delivering — stop the Gusto path and say so; the run sheet path is the outcome.

Pull, tool by tool:

InputToolRead it like this
Hourslist_time_records (period start and end)Check source first. native: shifts with clock-in, clock-out, breaks. third_party: timesheets; get_time_sheet on a timesheet's top-level id for per-day lines. none: no hours here, use the spreadsheet path.
Leave takenlist_time_off_requests (period, status: approved)Each approved day is paid as PTO or sick, not as worked. Pending is a flag. Notes are withheld by the tool; do not ask for them.
Balancesget_time_off_balancesAvailable, accrued, used, pending per policy. Policy names need the time-off-policies scope; without it match on policy uuid. Feeds the over-balance check.
Roster, rates, classificationslist_employees and its compensationsEmployment status and the active flag are separate fields (below).
Prior runlist_payrolls, get_payrollThe last processed run's per-person totals, for the comparison.

A missing punch the owner fills in is written with record_time, per Step 2 of the SKILL.md — owner-stated times only, shown first. The required parameters and the id and re-read traps are in the record_time row of ../../../shared/connector-call-shapes.md; this file does not repeat them.

Rates come from Gusto, never from the timesheet. A rate written on a paper timesheet is a note, not a record.


Raw lines 36 to 57
58## Source: QuickBooks Payroll
60Equal footing with Gusto, not a lesser path. Pull the employee roster, pay type and rate with its frequency, employment status, PTO policy balances, the pay schedule and frequency, and the last completed run for the prior-period comparison. The run detail carries per-employee gross pay, hours, and the source of those hours, so a timesheet-sourced entry is distinguishable from a manual one.
62Rates come from the payroll record here too, never from the timesheet.
64Three things to get right on this source:
66- **Employment status and the active flag are separate fields.** Someone flagged active can still be not-on-payroll or on paid leave. Read both before including anyone.
67- **One employee can carry many pay rates.** Most sit at zero hours. Total from the rate with hours against it, not the first one returned.
68- **The employee roster pages.** Read every page before totaling; a partial roster silently shorts whoever fell off the end.
70---

Source: QuickBooks Payroll

Equal footing with Gusto, not a lesser path. Pull the employee roster, pay type and rate with its frequency, employment status, PTO policy balances, the pay schedule and frequency, and the last completed run for the prior-period comparison. The run detail carries per-employee gross pay, hours, and the source of those hours, so a timesheet-sourced entry is distinguishable from a manual one.

Rates come from the payroll record here too, never from the timesheet.

Three things to get right on this source:

  • Employment status and the active flag are separate fields. Someone flagged active can still be not-on-payroll or on paid leave. Read both before including anyone.
  • One employee can carry many pay rates. Most sit at zero hours. Total from the rate with hours against it, not the first one returned.
  • The employee roster pages. Read every page before totaling; a partial roster silently shorts whoever fell off the end.

Raw lines 58 to 71
72## Source: spreadsheet upload
74The fallback path, and a common one. Small crews run on paper, a shared sheet, or a photo of a whiteboard.
76Accept any reasonable layout and map it. Expected columns, however they are named:
78- Employee name or ID
79- Date
80- Time in, time out
81- Break minutes, or a flag that breaks are already deducted
82- Hours, if the sheet is already totaled
83- Job, class, or cost code, if tracked
84- Pay type: regular, PTO, holiday, unpaid
86**Ask which convention the sheet uses for breaks.** A sheet that already nets out lunch, processed as though it doesn't, shortchanges everyone by half an hour a day. This one question prevents the most common upload error there is.
88When the sheet is already totaled, still recompute from the punches when punches exist. When only totals exist, use them and say so — the anomaly checks that depend on punch times will not run, and the owner should know which safety nets are off.
90---

Source: spreadsheet upload

The fallback path, and a common one. Small crews run on paper, a shared sheet, or a photo of a whiteboard.

Accept any reasonable layout and map it. Expected columns, however they are named:

  • Employee name or ID
  • Date
  • Time in, time out
  • Break minutes, or a flag that breaks are already deducted
  • Hours, if the sheet is already totaled
  • Job, class, or cost code, if tracked
  • Pay type: regular, PTO, holiday, unpaid

Ask which convention the sheet uses for breaks. A sheet that already nets out lunch, processed as though it doesn't, shortchanges everyone by half an hour a day. This one question prevents the most common upload error there is.

When the sheet is already totaled, still recompute from the punches when punches exist. When only totals exist, use them and say so — the anomaly checks that depend on punch times will not run, and the owner should know which safety nets are off.


Raw lines 72 to 91
92## Normalizing
94Produce one row per person per day:
96```
97person | date | in | out | break_min | regular | ot | pto | holiday | job
98```
100Rules that keep this honest:
102- A shift crossing midnight belongs to the day it started, unless the owner's policy says otherwise
103- Overlapping entries for one person are never merged automatically — they are flagged
104- A row with an in and no out gets hours recorded as unknown, not estimated
105- Rounding follows the owner's stated policy; with no policy, do not round at all
107---

Normalizing

Produce one row per person per day:

person | date | in | out | break_min | regular | ot | pto | holiday | job

Rules that keep this honest:

  • A shift crossing midnight belongs to the day it started, unless the owner's policy says otherwise
  • Overlapping entries for one person are never merged automatically — they are flagged
  • A row with an in and no out gets hours recorded as unknown, not estimated
  • Rounding follows the owner's stated policy; with no policy, do not round at all

Raw lines 92 to 108
109## Worked example
111Okonkwo Mechanical, week ending 3/15, five on the crew.
113- Gusto not connected. Ray uploaded a shared sheet with in and out times, breaks not deducted.
114- Confirmed: breaks are 30 minutes unpaid, taken daily, not punched.
115- Roster matched last period except one new apprentice, Dee, started Wednesday.
116- One row for Marcus on 3/12 has a 6:40 AM in and no out.
118Reported: 5 people, 214 hours readable, 1 shift with no clock-out (Marcus, Thursday), 1 new hire to confirm hours for (Dee, started 3/12).

Worked example

Okonkwo Mechanical, week ending 3/15, five on the crew.

  • Gusto not connected. Ray uploaded a shared sheet with in and out times, breaks not deducted.
  • Confirmed: breaks are 30 minutes unpaid, taken daily, not punched.
  • Roster matched last period except one new apprentice, Dee, started Wednesday.
  • One row for Marcus on 3/12 has a 6:40 AM in and no out.

Reported: 5 people, 214 hours readable, 1 shift with no clock-out (Marcus, Thursday), 1 new hire to confirm hours for (Dee, started 3/12).

Raw lines 109 to 118