Turn ClickUp tracked time into QuickBooks invoices each Friday

By General Input

Open one screen every Friday to review the week's tracked hours client by client, fix what is wrong, then raise draft invoices in QuickBooks.

Integrations

  • ClickUp
  • QuickBooks Online
  • Google Sheets

Type

App

Categories

  • Finance
  • Operations

Build me an internal billing app for my services team. We run everything in ClickUp and track time against tasks there, but ClickUp has no invoicing of its own, so every Friday I have to rebuild the week's numbers by hand before I can bill anyone. I want to open this app on a Friday, review the week client by client, fix the handful of things that are always wrong, and then push draft invoices into QuickBooks Online.

The main screen is a week picker with a client by client breakdown underneath it. Default it to the week that is just ending, with arrows to step back through previous weeks. Load the week's time using Get Time Entries for the workspace, passing the week's start and end. Remember that ClickUp timestamps are Unix epoch milliseconds and that team means workspace in the v2 API, so the workspace id is what the time entry call wants. Entry durations also come back in milliseconds.

Group the time by client. A client is a ClickUp Space or Folder, and I want to choose which level to group at in settings, because some workspaces put each client in their own Space and others use a Folder per client inside one Space. Build the hierarchy with Get Spaces for the workspace, Get Folders for each Space, and Get Lists for each Folder plus the folderless Lists in each Space. That gives you a map from list to folder to space, and each time entry's task tells you which list it belongs to, so every entry rolls up to exactly one client. Use Get Filtered Team Tasks to resolve task details in bulk rather than fetching tasks one at a time, and note it is paginated at 100 per page. Cache the space, folder and list hierarchy for the session, because lower ClickUp plans are limited to 100 requests per minute and rebuilding the tree on every interaction will hit that.

Each client row shows total tracked hours, billable hours, non billable hours, and the amount those billable hours come to at that client's rate. Work out billable versus non billable from time entry tags. Pull the workspace's tag vocabulary with Get Time Entry Tags and let me nominate in settings which tags mean non billable, since every team names them differently. Anything untagged counts as billable by default, and I want that default to be a setting too.

Clicking a client row expands it into a per person timesheet for that week. Group the entries by team member, then by task underneath, showing the date, duration, the entry description, and its tags. In this view I need to do three things. First, flag an individual entry as non billable, or flag it back to billable, without touching the hours themselves. Second, correct a thin or vague entry description, because half of them say things like fixes and that cannot go in front of a client. Third, see the tasks that were clearly worked on during the week but have no tracked time at all against them, so I can chase the person before the numbers go out.

For that last one, use Get Filtered Team Tasks scoped to the client's spaces and lists, filtered to tasks updated during the selected week, and show any that have no matching time entries in the week as a warning list on the client. It should be visible but not alarming, just a heading like worked with no time tracked and the task names underneath with their assignees.

Store my billable flags and description corrections in the app's own storage, keyed by time entry id and week, so they are what the invoice is built from and so reopening the week later shows the same picture. Corrections should never silently change ClickUp. Alongside each corrected description, offer a small action to push the corrected text back to ClickUp using Update Time Entry, so the source stays clean when I want it to, and mark in the app which corrections have been pushed. If I flag an entry non billable, optionally apply the workspace's non billable tag back to that entry with Add Tags to Time Entries, and Remove Tags from Time Entries when I flag it back to billable. Both of those write backs are opt in per client in settings, off by default.

Every client needs a settings panel holding an hourly rate, a rounding rule, a minimum billable increment, the QuickBooks customer this client bills to, and whether to invoice one line per project or one line per task. Rounding rules should cover exact time, round to the nearest increment, and always round up, with the increment itself configurable, typically six or fifteen minutes. The minimum billable increment is applied per line item, so a task with four minutes on it bills at the minimum rather than at four minutes. Apply rounding after summing a line item, not to each individual entry, otherwise the rounding compounds and the totals drift. Show both the raw and the rounded hours in the client breakdown so I can see exactly what rounding is doing before I approve anything.

When a week looks right for a client I hit Approve on that client's row. The handler sums the billable time per project or per task depending on the setting, applies that client's rounding and minimum increment, and builds one line item per project or task at the client's rate, using the corrected descriptions as the line descriptions. It then creates a draft invoice in QuickBooks Online with Create Invoice. Do not have it email the invoice, I want to review the wording in QuickBooks and send it myself.

For the customer link, the app stores the QuickBooks customer id against each client the first time it is set, and confirms it is still valid with Read Customer when the settings panel opens. If a client has no QuickBooks customer mapped yet, fall back to Create Customer, using the client name from ClickUp, then save the returned id against that client so every later week reuses it. Never create a customer for a client that already has one mapped.

Every approved week also appends a row to a Google Sheets audit log using Append Values. One row per client per week, carrying the week start and end dates, the client name, hours tracked, hours billable, hours actually billed after rounding, the rate, the invoice total, the QuickBooks invoice id, who approved it, and the approval timestamp. Having tracked and billed side by side in the log is the whole point, because that difference is what I get asked about later.

Keep an approval ledger in the app's storage so a week and client combination that has already been approved is locked, shows the invoice it produced, and cannot be double invoiced by accident. Let me deliberately reopen a locked week if something was genuinely wrong, and make it clear when I do that a new invoice will be created rather than the old one being amended. On the week picker, show at a glance which clients are approved, which are still to review, and which are blocked because they have no rate or no QuickBooks customer set.

The audience is me, the person who runs billing, so density beats decoration. I want the whole week readable without scrolling wherever possible, clear totals, and edits that save immediately without a separate save button. If a client has zero tracked time for the week, keep the row visible but muted, because an agency client with no hours in a week is itself worth noticing.

Related prompts

Explore more prompts
Call overdue Xero customers with an AI collections agentLocal listing health board for every location you manageLet support send one-off Loops emails without an engineerStop cold emails to anyone with a live deal in PipedriveiMessage campaign console with pre-flight checks and delivery boardLinkedIn Ads budget pacing dashboard for every client accountFront desk appointment confirmation board for the next 3 daysGive your team Looker numbers without buying more seatsBuild audience segments from product usage and push to LoopsTurn the people who engage with your posts into Pipedrive leads