Skip to content

Epic 09: Timesheets

Overview

The Timesheets Epic enables managers and workers to efficiently manage weekly work hours from generation through payroll submission. This workflow-driven module provides managers with clear visibility of worker hours requiring review, streamlined approval and editing capabilities, and automated payroll submission. Workers benefit from transparent timesheet reviews, and access to payslips once paid. The system ensures payroll is not blocked by reviews while maintaining accuracy.

Business Value

  • Manager Side (Desktop) Managers review and approve weekly timesheets in a dedicated "Timesheets" section with two tabs (Pending and Approved). The experience centers around auto-generated timesheets that can be edited before submission for payroll. Managers can modify time blocks, mark absences with reasons, and submit hours before the Thursday 00:00 deadline. If the deadline passes, the system auto-approves suggested hours to maintain payroll flow. All approved timesheets show comprehensive status tags (mutation, absence, auto-approved, paid, corrected) to track the complete lifecycle. Worker Side (Mobile) Workers review their weekly timesheets in a mobile-optimized interface with two tabs (New and Approved). Each timesheet card shows week details, job information, and total hours. Workers can view daily time blocks and confirm reviewed status before the Thursday 15:00 deadline. If the deadline passes, the system auto-submits suggested hours to maintain payroll flow. Once timesheets are paid, workers can access their payslips directly from the timesheet view. Key Workflows System generates suggested hours every Monday 00:00 based on offer agreements. Manager receives notification at 06:00 (configurable). Manager reviews and can edit time blocks, start/end times, or mark absences. Manager submits for payroll or timesheet auto-submits Thursday 00:00. Worker reviews timesheet and marks as reviewed or timesheet auto-approves Thursday 15:00. Hours are sent to MySolution for payroll processing Thursday 15:00. Payslip generated by end of following Friday. All workflows optimize for clarity, speed, mobile responsiveness, and payroll continuity. Key statuses, actions, and transitions are surfaced through clear UI flows and real-time updates, with empty state messaging throughout. After MVP: Dispute resolution operates independently from payroll. Worker disputes after submission by providing reason. Timesheet moves to Disputed tab for both parties and receives "disputed" tag. Manager can propose update (edit timesheet) or reject dispute with explanation. Worker can accept update/decision (closes dispute) or resubmit with new details. If resolved after payroll runs, correction is applied in next batch. Opening the dispute is available for only 4 most recent timesheets. Corrections only available while financial year is open.

Solution Concept

This epic implements integrated timesheet management for both managers and workers: Manager Side (Desktop) Managers review and approve weekly timesheets in a dedicated "Timesheets" section with two tabs (Pending and Approved). The experience centers around auto-generated timesheets that can be edited before submission for payroll. Managers can modify time blocks, mark absences with reasons, and submit hours before the Thursday 00:00 deadline. If the deadline passes, the system auto-approves suggested hours to maintain payroll flow. All approved timesheets show comprehensive status tags (mutation, absence, auto-approved, paid, corrected) to track the complete lifecycle. Worker Side (Mobile) Workers review their weekly timesheets in a mobile-optimized interface with two tabs (New and Approved). Each timesheet card shows week details, job information, and total hours. Workers can view daily time blocks and confirm reviewed status before the Thursday 15:00 deadline. If the deadline passes, the system auto-submits suggested hours to maintain payroll flow. Once timesheets are paid, workers can access their payslips directly from the timesheet view. Key Workflows System generates suggested hours every Monday 00:00 based on offer agreements. Manager receives notification at 06:00 (configurable). Manager reviews and can edit time blocks, start/end times, or mark absences. Manager submits for payroll or timesheet auto-submits Thursday 00:00. Worker reviews timesheet and marks as reviewed or timesheet auto-approves Thursday 15:00. Hours are sent to MySolution for payroll processing Thursday 15:00. Payslip generated by end of following Friday. All workflows optimize for clarity, speed, mobile responsiveness, and payroll continuity. Key statuses, actions, and transitions are surface

Features and User Stories

9.1 Change Offer Modal

User Story:

As a manager I want to enter shift hours while creating an offer for the candidate So that weekly timesheets can be auto-generated

Описание: The "Send Job Offer" modal is enhanced to include schedule configuration pulled from the job posting. Managers can review and adjust the number of time blocks a day, specific block start - end times, and working days. This schedule information becomes the part of the offer agreement and serves as the baseline for automatic weekly timesheet generation once the placement becomes active. alt size=16 style="background-blend-mode:normal;background-clip:content-box;background-position:50% 50%;background-color:rgba(0,0,0,0);background-image:var(--sf-img-16);background-size:100% 100%;background-origin:content-box;background-repeat:no-repeat"> BlinkSoftware [HF] [Main]

Критерии приёмки: - Offer Modal Structure: - Change to the stepper with 3 steps: - Offer Details - existing offer modal fields remain unchanged: - Candidate name - Availability and onboarding status badges - Job ID and start-end dates info box - Start date picker - required - End date picker - required - Offer Expiration integer input field - required - default value is 5 days - Offer message text area (optional manager note) - Schedule Configuration - time blocks pulled from job posting (see details below) - Review & Submit - informational step before sending an offer - Buttons on steps: - 1 Offer Details - Cancel → closes modal without saving, returns to previous screen - Next → proceed to step 2 - 2 Schedule Configuration: - Back → return to step 1 - Next → proceed to step 3 - 3 Review & Submit: - Back → return to step 2 - Send Offer → send offer to a candidate, close the modal, return to page, save offer info for revisiting iа edited/renewed - Schedule Configuration: - “Hours per Week” info field - dynamically calculate hours per week based on time blocks below (nice to have) - Sum the hours from all time blocks of all days selected - If exceeds weekly hours of job posting - show the warning message “Note the number of hours per week exceeds the one indicated in this job posting” - Is not editable - "Working days" selector panel: - Seven day buttons: - Mon, Tue, Wed, Thu, Fri, Sat, Sun - Toggle selection (orange = selected, gray = not selected) - Default: - Pre-filled from job posting (Mon-Fri selected) - At least one day should be selected - All days can be selected - For each day: - Start Time input / picker (HH:MM format, 24-hour) - End Time input / picker (HH:MM format, 24-hour) - “Add block” button → adds another time block to the very same day - “Copy” button → copies the current time block to each day selected - “Delete” button → deletes the current time block - Default values pre-filled from job posting - Pre-filled Data from Job Posting: - When modal opens, system retrieves schedule data from associated job posting: - Number of shifts / time blocks per day (if there are multiple) - Start/end times for each time block - Working days pattern - Manager can review, add and modify any time blocks before sending offer - Validation Rules: - Start time may not be after end time (for overnight shifts), but moved as a new time block for the next day (like Tue 20:00-02:00 should be split into Tue 20:00-24:00 and Wed 00:00-02:00) - At least one working day must be selected - At least one time block must be configured - If 2+ time blocks / shifts selected for one day, they should be validated for overlaps - No time overlaps allowed - Start Date should be today or later (no past start date allowed) - End Date should be later than Start Date - Offer Expiration should be a positive nonzero integer value - No validation of Offer Expiration against Start Date for MVP - Review & Submit: - Manager reviews all info including new schedule fields - Fields can be edited only if returned to previous steps - If changed and returned to step 3 - most recent info is shown - Send Offer Workflow: - Click "Send Offer" button - System validates all fields - On successful validation: - Offer created with complete schedule information - Offer sent to candidate - Schedule data stored with offer record for edit/renewal - Application moves to Offers > New tab - Success notification - Offer data is stored for placement generation - Offer data used by timesheet generation system (see US 9.2) - On validation error: - Display error message highlighting invalid fields - Do not close modal - Edit / Renew Offer Workflow: - When editing / renewing an existing offer, modal pre-fills with previously saved schedule data - Same stepper modal structure, showing step 1 first - Manager can modify any editable field - Start Date should be today or later (no past start date allowed) - End Date should be later than Start Date - Offer Expiration should be a positive nonzero integer value - Cannot be updated once placement has been created - Visual Design: - Schedule section clearly separated from other fields - Working days buttons with clear selected/unselected states - Responsive layout maintaining readability - Time picker icons for easy interaction - nice to have - Timesheet Generation Integration: - Once offer accepted and placement becomes active: - System uses schedule data for Monday 00:00 timesheet generation - Creates time blocks matching time blocks - Applies working days pattern - See Epic

9.1.1 (не MVP)

9.2 Timesheets - Manager Pending Tab

User Story:

As a manager I want to review and approve auto-generated weekly timesheets before the payroll deadline So that I can ensure accurate hours are submitted for worker payment

Описание: The Pending tab ("To review" on the prototype) displays all newly generated timesheets requiring manager review and approval. The system auto-generates timesheets every Monday at 00:00 based on offer agreements, and managers receive notifications at 06:00 (configurable in Django Admin). Managers can review suggested hours, make edits if necessary, and submit before the Thursday 00:00 deadline. If the deadline passes, the system auto-approved the timesheet to prevent payroll delays. alt size=16 style="background-blend-mode:normal;background-clip:content-box;background-position:50% 50%;background-color:rgba(0,0,0,0);background-image:var(--sf-img-16);background-size:100% 100%;background-origin:content-box;background-repeat:no-repeat"> BlinkSoftware [HF] [Main]

Критерии приёмки: - Pending Tab Header: - Tab label: "Pending" with badge showing count of pending timesheets - Descriptive text: "The list of new timesheets for you to review, edit and approve" - Search & Filter: - Search bar: "Search by name or job postings..." - Search by worker name - Search by job posting - Clear search [x] button - Filter drawer with: - Filter by job (multi-select with Active/Archived parent categories) - Filter by week (single week selector) - If filters applied: "filter applied" indicator (orange dot on funnel icon) - Table Columns: - Worker: - Profile picture + Name + Job ID - Week number with sort capability - Planned: - Planned hours from offer - Current Hours: - Current total hours (may differ if edited) - Variance: - Difference between planned and current (0h if no changes) - Possible tags: mutation, absence - Actions: - Button panel with “Edit”, “Message”, “Submit for Payroll” buttons (show button name on hover) - Timesheet Generation: - Timesheets generated since placement (offer) Start Date until End Date + 1 week - System generates timesheets Monday 00:00 every week - Timesheets with zero hours are possible - Uses information from offer modal - Creates "Suggested" status timesheets - Manager receives notification "New Timesheets to approve" at Monday 06:00, time configurable in Django Admin (see epic 10) - Timesheet is featured as a single entry in single tab - no duplicates - Edit Timesheet Workflow: - Click Edit button → Opens drawer - Drawer displays: - Worker name and week header - Planned total vs Current total vs Variance responsive info block (see details below) - Daily time blocks for each day of week - For each day: - Day label (Mon, Tue, Wed, …) - Planned hours display - Current hours display - Start time picker - End time picker - "Mark as absent" button - Add time block button (+) - Delete time block button (trash icon) - "Save" button -> Saves changes without submitting - "Save & Submit" button -> Saves and submits for payroll → entry is moved to “Approved” tab - "Cancel" button -> Closes drawer without saving - On save: "mutation" tag added if any changes made - Variance column updates to reflect changes - End time picker is truncated to show options later than start time - Validation: - End time should be after start time in every time block - No time overlaps allowed within a day - Highlight red the invalid time blocks - nice to have - Responsive Info Block with Real-time Hours Calculation: - On first open: - “Planned” are pulled from offer data - hours per week - “Current” is the same - “Variance” = 0 - Once any time block added / edited / removed, or absence marked (on focus changed where applicalble): - “Planned” are pulled from offer data - hours per week - “Current” is dynamically calculated, comparing the sum of current time blocks against offer weekly hours - “Variance” value calculated as Current time - Planned time, and equals: - positive decimal number, if Current > Planned - negative decimal number, if Current < Planned - 0, if Current = Planned - On any next open: - “Planned” are pulled from offer data - hours per week - “Current” is sum of all current time blocks (previously edited) - “Variance” value calculated as Current time - Planned time, and equals: - positive decimal number, if Current > Planned - negative decimal number, if Current < Planned - 0, if Current = Planned - Mark Absence Workflow - see US

9.2.1 (не MVP)

9.3 Timesheets - Manager Approved Tab

User Story:

As a manager I want to view all approved timesheets and make corrections if needed So that I can fix any post-approval errors

Описание: The Approved tab displays all timesheets that have been successfully approved by manager (or auto-approved by the system). This includes timesheets that have been paid and those awaiting payroll. Managers can view comprehensive status tags, access correction capabilities for recent timesheets, and communicate with workers about approved hours. alt size=16 style="background-blend-mode:normal;background-clip:content-box;background-position:50% 50%;background-color:rgba(0,0,0,0);background-image:var(--sf-img-16);background-size:100% 100%;background-origin:content-box;background-repeat:no-repeat"> BlinkSoftware [HF] [Main]

Критерии приёмки: - Approved Tab Header: - Tab label: "Approved" with badge showing count - Descriptive text: "All timesheets that have been approved and are in payroll or paid" - Search & Filter: - Same search and filter capabilities as other tabs - Filter options: job, week, tags (last one - nice to have) - Search by worker name and job posting - Table Columns: - Worker: - Profile picture + Name + Job ID - Week number with sorting - For previous year: week number + year, like “W52, 2025” - nice to have - Planned: - Original planned hours - Current Hours: - Final approved hours - Variance: - Difference from planned - All applicable tags (mutation, absence, auto-approved, paid, corrected) - Actions: - Correct, Message - Status Tags Display: - Multiple tags can stack on single timesheet - Tags shown as pills with text - Tags order is by applied date (no fixed order) - Tooltip on hover shows tag meaning - nice to have - View Timesheet Details: - Click on row → Expands to show: - Daily breakdown with time blocks - Original planned vs current hours per day - Absence details if applicable - Correction history if applicable, with timestamps - Correct Timesheet Workflow: - "Correct" button available on timesheet row, active for current financial year - Click "Correct" → Opens edit drawer (same as in Pending tab) - Manager can: - Edit time blocks - Adjust start/end times - Mark absences - Add/remove time blocks - "Cancel" button -> Closes drawer without saving - No “Save” button - "Save & Submit" button → Submits correction and closes the drawer - On submit: - If timesheet not yet paid: - Changes applied immediately - "mutation" tag added - Worker receives notification - If timesheet already paid: - "corrected" tag added - Worker receives notification (epic 10) - Note: "Correction will be processed in next payroll" - “Correct" button is disabled if financial year closed: - Hover message: "Cannot correct timesheet as financial year is closed. - Please contact Cruits support for manual correction [email to be defined?]" - Correction Constraints: - Corrections only available while financial year is open - If year closed: - Display info message on Correct button hover - Separate finance process required for closed year corrections - Paid Tag: - "paid" tag on timesheet applied - once MySolution has finished payrolling (best case scenario) - at 16:00 each Friday (time configurable in Django Admin) if we cannot retrieve the payroll info from MySolution (most probable scenario) - Message Worker: - Click Message button → Opens chat thread - Auto-Approval Indicators: - "auto-approved" tag indicates system auto-submitted - Applies when manager missed Thursday 00:00 deadline - Timestamp shows auto-approval time - Sorting & Organization: - Sorting by week (Descending / Ascending) - Default sort: - Most recent week first - Pagination - standard for the project: - Rows per page input field (10 by default) - Page navigation: - First, Previous, Page number, Next, Last - Display: "1-N of N rows" and "Page n of N" - Empty States: - If no approved timesheets: "No approved timesheets yet. - Approved timesheets will appear here." - If no results from filters: "No approved timesheets match your filters" + "Reset all Filters" button

9.3.1 (не MVP)

9.4 Absence Management

User Story:

As a manager I want to mark and track worker absences with reasons So that I can accurately record when workers were not present and adjust their hours accordingly

Описание: The absence management feature allows managers to mark days as absent with specific reasons (no-show, leave, sick, holiday not worked) and optional notes. Marked absences adjust the timesheet hours, add absence tags, and provide clear visibility to both managers and workers about why hours differ from planned schedules. alt size=16 style="background-blend-mode:normal;background-clip:content-box;background-position:50% 50%;background-color:rgba(0,0,0,0);background-image:var(--sf-img-16);background-size:100% 100%;background-origin:content-box;background-repeat:no-repeat"> BlinkSoftware [HF] [Main]

Критерии приёмки: - Mark Absence Access: - Available in Edit (Update / Correct) drawer on all tabs - "Mark as absent" button displayed for each day - Button available for days with or without existing time blocks - Absence Modal: - Modal title: "Mark absence" - Close button (x) - Job Posting field (read-only, pre-filled) - Absence type dropdown selector with options: - No-show - Holiday (not worked) - Default selection: - No-show - Note/Reason text field (optional, 0-1500 characters) - Character counter: "0/1500" - "Cancel" button → Returns to edit drawer - "Submit" button → Applies absence - Absence Application: - On submit: - All existing time blocks for that day are removed - Day shows absence type and note (if any), truncated to 1 line and shown full on hover - Current hours reduced by removed time block hours of day with absence - Variance updated to reflect reduction - "absence" tag added to timesheet - Absence persists across edits - Can be removed by clicking “+” button on absence day, that adds a new time block there - Absence Display - Manager Side: - In edit drawer: - Day label with absence indicator - Absence type (like "Absence - Sick") - Note text (like "Note: - Flu symptoms") - Red status badge in the absence day - In expanded row - nice to have: - "Absence - [type]. Note: [text]" - In table: - "absence" tag visible - Absence Display - Worker Side: - In timesheet details modal: - Day label with date - "Absence - [type]. Note: [text]" - Red status badge in the absence day - On timesheet card: - "absence" tag visible - Remove Absence: - “+” button on absence day - Absence removed - New time block there, populated from Offer for that day, if none - time block from the previous day - Hours can be added / edited - If no other absences: "absence" tag removed from timesheet - Multiple Absences: - Multiple days can be marked as absent on same timesheet - Each absence can have different type and note - "absence" tag appears once regardless of number of absent days - Summary shows total days absent - nice to have - Absence Types Tooltips - nice to have: - No-show : Worker did not appear for scheduled shift - Leave : Worker took approved leave/vacation - Sick : Worker was ill and could not work - Holiday (not worked) : Public holiday where work was not required - Absence Impact on Hours: - Absent days count as 0 hours - Variance shows negative hours if planned time was scheduled - Total current hours reduced by absence - Absence Constraints: - Cannot mark absence on already-paid timesheet without creating correction - Absence on paid timesheet triggers "corrected" tag - Correction applied in next payroll batch

9.4.1 (не MVP)

9.5 Timesheets - Worker Side

User Story:

As a worker I want to review my weekly timesheets So that I can ensure I will be paid correctly for my work

Описание: The worker-side timesheet interface provides mobile-optimized access to review weekly hours, confirm accuracy, and access payslips. Workers receive timesheets after manager submission (or auto-submission at Thursday 00:00) and can mark them as reviewed . alt size=16 style="background-blend-mode:normal;background-clip:content-box;background-position:50% 50%;background-color:rgba(0,0,0,0);background-image:var(--sf-img-16);background-size:100% 100%;background-origin:content-box;background-repeat:no-repeat"> BlinkSoftware [HF] [Main]

Критерии приёмки: - Access Points: - “Work” page -> Timesheets button - orange dot indicator on an unread item there (new timesheet) - “View timesheet” button on corresponding notifications - Timesheets Page Header: - Page title: "My timesheets" - No tabs - Mobile-optimized interface - Filter button at top - Filter Drawer: - Filter button opens modal bottom sheet - Filter by placements: - Multi-select list with parent categories: - Active placements - Archived placements - Select all option - Filter by week: - Single-select week dropdown - Apply filters button - Reset filters button - Page Layout: - Shows all timesheets - new, auto-approved and payrolled - Explanation text: "Please review your new timesheets. - Note they will be auto-reviewed by the system weekly on Thu 15:00" - Card layout with: - Week number and date range (like "W41 · Oct 6 - Oct 12, 2025") - Job position and location (like "Warehouse Assistant, Rotterdam") - Hours summary: - Planned hours / Current hours (like "38.5h / 40h") - Tag if applicable: absence (no other tags) - "View Details" button - Sorted by most recent first - Orange unread do if timesheets is not reviewed - View New Timesheet Details: - Click "View Details" → Opens bottom sheet modal - Modal header: - "Weekly timesheet" - Week date range - Back button - Summary section: - Company name and job position info box - Total hours: [number] - Daily breakdown: - Day label (Mon, Tue, Wed, etc. + date) - Time range (like "08:00-16:00") - OR Absence indicator (like "Absence: - Sick, Note: - Flu symptoms") - OR "No blocks" for days off - Changed hours indicator, if there was mutation of timesheet: - “More hours worked”, if hours were added by manager - “Less hours worked”, if hours were subtracted by manager - Action buttons: - If this timesheet is not yet in “paid” status - "Confirm reviewed" (primary) - + Informational text: ""Review before Thu 15:00 and contact your manager if you think anything should be changed. - If resolved after payroll runs, correction is applied in next batch - so don't worry, it will be all figured out!"" - "Message" (secondary) → opens chat with manager - Confirm Reviewed Workflow: - Click "Confirm reviewed" button: - “Confirm Reviewed” button disappears - Success message: "Timesheet marked as reviewed" - Informational text changed to: "Marked as reviewed. - Corrections will be handled in the next batch if needed." - nice to have - Auto-Review: - If worker does not review by Thursday 15:00: - System marks timesheet as reviewed - Hours sent to payroll - No "auto-approved" tag added - Paid Timesheet Indicators: - "paid" tag on card and on details - Add the section to Timesheet details: "View payslip" link -> download payslip for that very week - Payslip generated by end of Friday following payroll Thursday (to be investigated in MySolution) - Message Manager: - Click "Message" button - Opens chat thread with manager - Chat displays job context - Pagination: - Lazy loading (standard for the project) - Empty States: - New: "No timesheets yet. - Once you have an active placement, here you will see new timesheets every week." - Notifications (see epic 6 & Improvements Epic): - New timesheet to review: "Your timesheet for week N is ready to review" - Auto-review: "Your timesheet for week N was automatically marked as reviewed" - Payslip ready: "Your have a new payslip ready"

9.5.1 (не MVP)

9.6 Timesheet Flow & Tag System

User Story:

As a system I want to track comprehensive timesheet lifecycle status and modifications So that managers and workers have clear visibility of timesheet state and history

Описание: The timesheet flow and tag system provides comprehensive logic on tracking of timesheet lifecycle, modifications, and payment status. Tags provide informational flags about actions taken on the timesheet. Sequence Diagram: Open Timesheet Statuses - Cruits-2026-01-29-121648.png

Критерии приёмки: - System Status Model (for BE only): - Suggested: - System-generated hours based on offer agreement - Applied when: - System generates timesheet Monday 00:00 - Action: - Create new timesheet entries for Manager in “Pending” tab - Next states: - Awaiting review (on manager submit or auto-submit) - Awaiting review: - Manager submitted hours for payroll, hours sent to worker - Applied when: - Manager submits OR Thursday 00:00 comes (auto-approve) - Action: - Timesheet moved to “Approved” tab for Manager, create new timesheet entries for Worker in “New” tab - Next states: - Reviewed, Approved - Auto-approved: - Manager not does submitted hours for payroll by Thursday 00:00, hours sent to worker - Applied when: - Thursday 00:00 comes - Action: - Create new timesheet entries for Worker in “New” tab, for Manager - entry moved to “Approved” tab with “auto-approved” tag applied - Next states: - Reviewed, Auto-reviewed, Approved - Reviewed: - Worker marked timesheet as reviewed - Applied when: - Worker clicks "Confirm reviewed" until Thursday 15:00 - Action: - Move entry to Approved tab (Worker) - Informational status, does not affect payroll flow - Immediately transitions to: - Approved - Auto-reviewed: - Worker has not marked timesheet as reviewed until Thu 15:00 - Applied when: there are no “Reviewed” status and Thursday 15:00 comes - Action: - Move entry to Approved tab (Worker), hours sent for payroll - Informational status, does not affect payroll flow - Immediately transitions to: - Approved - Approved: - Timesheet approved and sent to payroll - Applied when: - Worker reviews OR Thursday 15:00 and auto-reviewed - Action: - Entry featured in “Approved” tab for both Manager and Worker - Final state for workflow - Tag System: - mutation : Manager changed one or more days compared to suggested hours - Applied when: - Manager edits timesheet (time blocks, hours, dates) - Shown for Manager only - Permanent - absence : Day marked as absence (sick, leave, no-show, holiday) - Applied when: - Manager marks day as absent in edit drawer - Shown for both Manager and Worker - Permanent - auto-approved : System submitted hours after deadline - Applied when: - Thursday 00:00 auto-submit - Shown for Manager only - Permanent - paid : Payroll batch processed for this timesheet - Applied when: - MySolution confirms payroll OR payroll batch runs Thursday 15:00 and processes hours - Permanent - Shown for both Manager and Worker - Enables: - Payslip access for worker - corrected : Post-payroll correction made - Applied when: - Timesheet edited after payroll - Permanent - Shown for both Manager and Worker - Correction applied in next payroll batch - Tag Stacking: - Multiple tags can appear on single timesheet - Tags are additive and informational - Tags do not block payroll processing - Display order: mutation, absence, auto-approved, paid, corrected - Maximum visible tags: - Show "+4" indicator if more than 3 tags - Tag Visibility: - Manager side: - All tags visible in table and detail views - Worker side: - All tags, except “mutation” and “auto-approved”, are visible on cards - Tooltip on hover: - Shows tag meaning and application timestamp - nice to have

9.6.1 (не MVP)

9.7 (не MVP)

User Story:

As a manager I want to review and resolve worker timesheet disputes So that I can address worker concerns and ensure accurate payment

Описание: The Disputed tab ("Issues" on the prototype) displays all timesheets that workers have disputed. Workers open disputes when they believe submitted hours are incorrect. Managers can review dispute reasons, propose updates by editing the timesheet, or reject disputes with explanations. The dispute workflow allows back-and-forth resolution until both parties agree, while payroll continues based on last submitted hours.

Критерии приёмки: - Disputed Tab Header: - Tab label: "Disputed" with badge showing count of disputed timesheets - Descriptive text: "Timesheets that workers have disputed and require your attention" - Search & Filter: - Same search and filter as in Pending tab - Filter options: job, week, tags (last - nice to have) - Search by worker name and job posting - Table Columns: - Worker: - Profile picture + Name + Job ID - Week number with sorting - Planned: - Original planned hours - Current Hours: - Last submitted hours - Variance: - Difference from planned - Possible tags: mutation, absence, auto-approved, paid, corrected - Actions: - Update Timesheet, Reject Dispute, Message - Dispute Flow: - Worker submits dispute - Client updates: - Manager edits timesheet -> worker notified → “dispute resolved” tag applied and entry moves to Approve tab. - If this entry has “paid” tag (payrolled already), apply tag “corrected” as well - Client rejects: - Manager rejects dispute -> worker notified → “dispute rejected” tag applied and entry moves to Approve tab - Unlimited dispute rounds until resolution (up to 4 weeks, while “Dispute” button is still available, see US 9.6) - View Dispute Details: - Click on row → Expands to show: - Original submitted hours (daily breakdown) - Dispute reason from worker with timestamp - Dispute timestamp - Current hours if updated - Update history if multiple dispute rounds - Update Timesheet: - Click "Update" button → Opens edit drawer (same as Pending tab) - Manager can: - Edit time blocks - Adjust start/end times - Mark absences - Add/remove time blocks - "Save & Send Update" button: - Dispute status changes to "dispute resolved" - Worker receives notification - Timesheet moves to Approved tab - Worker can accept update or resubmit dispute - If resubmitted: - New dispute reason added, entry returns to Disputed tab, notifications is sent to manager - Reject Dispute Workflow: - Click "Reject Dispute" button - Modal opens: "Reject Dispute" - Message: "Are you sure you want to reject this dispute from [worker name]?" - Explanation text field (required, 20-1500 characters) - Placeholder text: “Explain why the original hours are correct” - "Reject" button → Submits rejection - "Cancel" button → Returns to table - On reject: - Entry moves to Approved tab - "dispute rejected" tag added - Worker receives notification with explanation - Worker can accept decision or resubmit with new details - If resubmitted: - New dispute reason added, entry returns to Disputed tab, notifications is sent to manager - Message Worker: - Click Message button → Opens chat thread - Tags Applied: - "mutation": Applied if manager made changes - "absence": Applied if absences marked - "corrected": Applied if changes made after the payroll - “paid”: Applied once already payrolled (on Thu 15:00) - "dispute resolved": Applied when dispute closed with manager update (in Approved tab) - "dispute rejected": Applied when dispute closed with manager rejection (in Approved tab) - Payroll Impact: - Disputes do not block payroll - Payroll runs Thursday 15:00 with last submitted hours - If dispute resolved after payroll: - Correction applied in next batch - "corrected" tag added for post-payroll changes - Pagination - standard for the project: - Rows per page input field (10 by default) - Page navigation: - First, Previous, Page number, Next, Last - Display: "1-N of N rows" and "Page n of N" - Empty States: - If no disputed timesheets: "No disputed timesheets. - Disputes from workers will appear here." - If no results from filters: "No timesheets match your filters" + "Reset all Filters" button - Full Sequence Diagram with Dispute Logic: - Full Sequence Diagram with Dispute Logic: - Open Timesheet Statuses - Cruits-2026-01-27-123632.png - Mermaid Code - sequenceDiagram - participant System as System (Cruits Engine) - participant Manager - participant Worker - participant Payroll - Note over System,Payroll: - Weekly Timesheet Cycle - rect rgb(240, 248, 255) - Note over System: - Monday 00:00 - Timesheet Generation - System->>Manager: - Generate timesheet (Status: - Suggested) - Note right of Manager: - Timesheet in "Pending" tab - rect rgb(255, 250, 240) - Note over Manager: - Manager Review Period (Mon-Wed) - alt Manager edits timesheet - Manager->>Manager: - Edit hours/dates/blocks - Note right of Manager: - Tag: "mutation" applied - else Manager marks absence - Manager->>Manager: - Mark day as absent - Note right of Manager: - Tag: "absence" applied - rect rgb(240, 255, 240) - Note over Manager,Worker: - Thursday 00:00 - Submission Deadline - alt Manager submits before Thursday 00:00 - Manager->>System: - Submit timesheet - System->>Manager: - Move to "Approved" tab - System->>Worker: - Send timesheet (Status: - Awaiting review) - Note right of Worker: - Timesheet in "New" tab - else Thursday 00:00 auto-submit - System->>System: - Auto-approve timesheet - System->>Manager: - Move to "Approved" tab - Note right of Manager: - Tag: "auto-approved" applied - System->>Worker: - Send timesheet (Status: - Auto-approved) - Note right of Worker: - Timesheet in "New" tab - rect rgb(255, 245, 238) - Note over Worker: - Worker Review Period (Thu-Thu 15:00) - alt Worker confirms review (before Thu 15:00) - Worker->>System: - Click "Confirm reviewed" - System->>Worker: - Status: - Reviewed → Approved - Note right of Worker: - Move to "Approved" tab - System->>Payroll: - Send hours for payroll - else Worker disputes timesheet - Worker->>System: - Click "Dispute" + submit note - System->>Worker: - Status: - Disputed (Open) - System->>Manager: - Status: - Disputed (Open) - Note over Manager,Worker: - Entry moved to "Disputed" tab - alt Manager updates hours - Manager->>System: - Update disputed hours - System->>Worker: - Status: - Disputed (Updated) - Note right of Worker: - Show "Accept Update" / "Still Incorrect" - alt Worker accepts update - Worker->>System: - Accept update - System->>Manager: - Status: - Approved - System->>Worker: - Status: - Approved - Note over Manager,Worker: - Tag: "dispute resolved" applied - System->>Payroll: - Send hours for payroll - else Worker disputes again - Worker->>System: - Click "Still Incorrect" + note - System->>Manager: - Status: - Disputed (Open) - Note over Manager,Worker: - Back to Open dispute - else Manager rejects dispute - Manager->>System: - Reject dispute + note - System->>Manager: - Status: - Approved - System->>Worker: - Status: - Approved - Note over Manager,Worker: - Tag: "dispute rejected" applied
Entry in "Approved" tab - System->>Payroll: - Send hours for payroll - else Thursday 15:00 - No worker action - System->>System: - Auto-review - System->>Worker: - Status: - Auto-reviewed → Approved - Note right of Worker: - Move to "Approved" tab - System->>Payroll: - Send hours for payroll - rect rgb(255, 240, 245) - Note over Payroll: - Thursday 15:00 - Payroll Batch Processing - Payroll->>Payroll: - Process approved hours - Payroll->>System: - Confirm payroll completion* - System->>Manager: - Apply tag: "paid" - System->>Worker: - Apply tag: "paid" - Note over Worker: - Payslip access enabled - rect rgb(248, 248, 255) - Note over Manager,Worker: - Post-Payroll Corrections (if needed) - opt Dispute resolved after payroll - Manager->>System: - Edit timesheet after payroll - System->>Manager: - Apply tag: "corrected" - System->>Worker: - Apply tag: "corrected" - Note over System,Payroll: - Correction applied in next batch - Note over System,Payroll: - Key Principle: - Payroll not blocked by worker review
Manager submission drives payout

9.7.1 For later versions: Dispute escalation to admin/support Dispute analytics (common reasons, resolution time) Dispute temp