53 min readDeterministic automation

Implementation Guide: Auto-generate time and expense reports from calendar and project tracking data

Step-by-step implementation guide for deploying AI to auto-generate time and expense reports from calendar and project tracking data for Professional Services clients.

Hardware Procurement

Fujitsu ScanSnap iX1600 Document Scanner

Fujitsu / RicohPA03770-B615Qty: 1

$400 MSP cost / $525 suggested resale to client

High-speed duplex scanner for digitizing paper expense receipts, vendor invoices, and travel documents. OCR output feeds into the expense categorization workflow. Only required if the client has significant paper receipt volume; most clients can use smartphone camera capture instead.

Apple iPad 10th Generation 64GB Wi-Fi

AppleMPQ03LL/AQty: 1

$349 MSP cost / $475 suggested resale (with stand and case)

Optional shared kiosk device for field teams or reception areas enabling quick time clock-in/out and receipt photo capture. Mounted with a Heckler Design WindFall Stand ($100). Only needed for firms with non-desk workers or shared workspace environments.

Intel NUC 13 Pro Mini PC

Intel / ASUS (various resellers)RNUC13ANHI50001 (i5-1340P, Barebone)Qty: 1

$450–$650 MSP cost (barebone + 16GB RAM + 256GB NVMe) / $750 suggested resale configured

On-premises server for self-hosted n8n automation engine. Only required for clients with strict data residency requirements or those who prefer to avoid cloud automation platform fees. Configured with Ubuntu Server 22.04 LTS and Docker. Most clients will use cloud-based Power Automate or Zapier instead, making this unnecessary.

Software Procurement

Microsoft 365 Business Standard

MicrosoftPer-seat SaaS (monthly/annual), provisioned via CSP

$12.50/user/month (CSP cost ~$10.50); includes Power Automate standard connectors

Core productivity suite providing Exchange Online (Outlook Calendar), Teams, SharePoint, and OneDrive. The calendar data from Exchange Online is the primary input source for auto-generated time entries. Power Automate with standard connectors is included at no additional cost.

Microsoft Power Automate Premium

MicrosoftPer-user SaaS add-on via CSPQty: 1–3 admin accounts (typically)

$15/user/month

Required only if the implementation uses premium connectors (e.g., Dataverse, custom connectors to BigTime/Scoro APIs, or HTTP webhook actions). For basic Outlook Calendar → SharePoint flows, the included standard license suffices.

BigTime Software — Advanced Plan

BigTime SoftwareAdvanced PlanQty: 25 users

$35/user/month ($875/month for 25 users); MSP partner discount typically 15–25%

Primary PSA/time-and-expense platform for mid-size professional services firms. Handles project setup, billing rate cards, time entry management, expense tracking, invoice generation, and QuickBooks/Xero sync. The automation engine pushes draft time entries here via BigTime's REST API.

Harvest Pro (Alternative to BigTime for smaller firms)

HarvestPer-seat SaaS (monthly/annual)Qty: 25 users

$12/user/month ($10.80 annual); $270/month for 25 users

Lightweight alternative to BigTime for firms under 25 people or those prioritizing simplicity. Excellent calendar integration, built-in expense tracking with receipt upload, and native invoicing with Stripe/PayPal. Better fit for agencies and small consultancies.

Zapier Team Plan (Alternative automation engine)

ZapierUsage-based SaaS (tasks/month)Qty: 2,000 tasks/month

$69/month for 2,000 tasks; additional tasks at tiered pricing

Alternative to Power Automate for non-Microsoft shops or when Google Workspace is the primary calendar platform. 7,000+ pre-built app connectors make integration with niche PSA tools simpler. Recommended when the client uses Google Workspace + Asana/Monday.com + Harvest.

Make (formerly Integromat) — Pro Plan

Make (Celonis)Usage-based SaaS (operations/month)

$16/month for 10,000 operations; significantly more cost-effective than Zapier for high-volume flows

Budget-friendly alternative automation engine with visual scenario builder. Best for MSPs comfortable with more technical configuration who want to minimize per-operation costs. Excellent for complex multi-branch logic.

n8n Community Edition (Self-hosted)

n8n GmbHOpen-source (Apache 2.0 with Commons Clause); free self-hostedQty: Unlimited workflows and executions

$0 software cost; hosting on Intel NUC or cloud VM ($30–$50/month)

Self-hosted automation engine for clients requiring on-premises data processing or MSPs wanting zero per-execution cost. Unlimited workflows and executions. Requires Docker and basic Linux administration.

Ramp Corporate Card + Expense Management

Ramp FinancialFree tier (no monthly fee); Plus at $15/user/month

$0/month (Free tier) or $375/month for 25 users on Plus

Automated expense management with corporate card. Auto-matches receipts via OCR, codes transactions to GL accounts, and enforces spend policies. Integrates with QuickBooks Online, Xero, NetSuite, and Sage. The automation engine pulls categorized expenses from Ramp's API to attach to project time entries.

QuickBooks Online Plus

IntuitCompany-wide SaaS subscriptionQty: Company-wide, not per-user

$99/month

Downstream accounting platform receiving synced invoices, approved expenses, and billable time data from BigTime/Harvest. Most professional services firms already have this; the implementation connects the PSA's native QuickBooks sync.

Prerequisites

Installation Steps

Step 1: Discovery & Current State Audit

Conduct a structured discovery session with the client's project champion, managing partner, and controller/bookkeeper. Document the current time entry workflow (manual, spreadsheet, existing tool), calendar usage patterns, project/task tracking tools, billing rate cards, expense policies, and compliance requirements (FLSA, SOX, DCAA, GDPR). Audit existing calendar hygiene: how consistently employees name meetings, tag clients, and categorize events. This directly impacts automation accuracy. Map every active client and project to a unique code. Identify the 3–5 highest-volume calendar-to-timesheet patterns (e.g., 'Client meeting', 'Internal standup', 'Travel day') that will form the initial automation rules.

Note

Use a standardized discovery questionnaire. Typical duration: 2–3 hours. Deliverable: a 'Current State & Requirements' document that the client signs off on before proceeding. Key risk: if calendar hygiene is poor (vague meeting titles, no client tagging), the automation will have low match rates. Plan a calendar hygiene training session as part of Phase 5 rollout.

Step 2: Register Azure AD Application for Microsoft Graph API Access

Create an app registration in Microsoft Entra ID (Azure AD) that the automation engine will use to read calendar events and user profiles via the Microsoft Graph API. This is the secure OAuth 2.0 identity that Power Automate (or n8n/Make) uses to access Outlook Calendar data without storing user passwords.

1
Navigate to Azure Portal > Entra ID > App registrations > New registration
2
Name: 'TimeAutomation-CalendarReader'
3
Supported account types: 'Accounts in this organizational directory only'
4
Redirect URI: https://global.consent.azure-apim.net/redirect (for Power Automate) or your n8n OAuth callback URL
5
After registration, note the Application (client) ID and Directory (tenant) ID
6
Add API Permissions — Microsoft Graph > Application permissions: Calendars.Read (Read calendars in all mailboxes), User.Read.All (Read all users' full profiles)
7
OR for delegated (per-user) access — Microsoft Graph > Delegated permissions: Calendars.Read, User.Read
8
Create a client secret: Certificates & secrets > New client secret
9
Description: 'TimeAutomation-Secret-2025', Expiry: 24 months
10
COPY THE SECRET VALUE IMMEDIATELY — it will not be shown again
11
Grant admin consent: API permissions > Grant admin consent for [Tenant Name]
12
Record these values securely in the client's IT documentation (e.g., IT Glue)
Values to record securely after app registration
text
- Application (Client) ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
- Directory (Tenant) ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
- Client Secret: ********** (store in Azure Key Vault or MSP secret manager)
Note

For Google Workspace clients, create a Google Cloud project instead: console.cloud.google.com > APIs & Services > Credentials > Create OAuth 2.0 Client ID. Enable the Google Calendar API and People API. Use domain-wide delegation for server-to-server access. Application permissions (vs. delegated) are recommended for automation scenarios so the flow runs without individual user sign-in. Requires Global Admin consent. Client secret expires in 24 months — set a calendar reminder to rotate it.

Step 3: Provision and Configure the PSA / Time Tracking Platform

Set up BigTime (primary recommendation for 10–50 person firms) or Harvest (for smaller firms). This includes creating the account, configuring the organizational structure, importing the project/client taxonomy, setting up billing rate cards, configuring approval workflows, and enabling API access for the automation engine.

1
Create BigTime account via partner portal (MSP partner pricing)
2
Organization Setup: Settings > Firm Settings > Company Info (name, address, fiscal year) and Settings > Firm Settings > Time & Expense Policies
3
Import Staff: Settings > Staff > Import from CSV
4
Import Clients & Projects: Settings > Clients > Import from CSV and Settings > Projects > Import from CSV
5
Configure Billing Rate Cards: Settings > Billing > Rate Cards — create rate card per client or use default by role, map Role + Project Type → Billing Rate
6
Configure Approval Workflow: Settings > Approvals > Time Approval and Settings > Approvals > Expense Approval
7
Enable API Access: Settings > Integrations > API — generate API key and record securely
8
Connect QuickBooks Online: Settings > Integrations > QuickBooks Online — authorize OAuth connection, map clients and expense categories, set sync frequency
BigTime Time & Expense Policy configuration values
text
# Time & Expense Policy Settings
Time rounding: nearest 6 minutes (0.1 hour) — standard for professional services
Require project/task on all entries: YES
Allow future-dated entries: NO
Expense receipt required for entries over $25: YES
Staff CSV import format and example
csv
FirstName, LastName, Email, Role, DefaultBillRate, CostRate, Department
John,Smith,jsmith@clientdomain.com,Senior Consultant,175.00,85.00,Advisory
Clients & Projects CSV import format and example
csv
ProjectCode, ProjectName, ClientName, BudgetHours, BudgetAmount, StartDate, EndDate
ACME-2025-01,ACME Q1 Advisory,Acme Corp,500,87500,2025-01-01,2025-03-31
BigTime approval workflow configuration
text
Time Approval:
  Level 1: Direct Manager
  Level 2: Project Manager (for entries > 8 hours/day)

Expense Approval:
  Level 1: Direct Manager
  Level 2: Controller (for expenses > $500)
BigTime API and QuickBooks Online integration settings
text
BigTime API Base URL: https://iq.bigtime.net/BigtimeData/api/v2/

QuickBooks Online Sync:
  Map: BigTime clients → QBO customers
  Map: BigTime expense categories → QBO expense accounts
  Sync frequency: Daily at 2:00 AM
Harvest API access configuration
text
Harvest API Base URL: https://api.harvestapp.io/v2/
Auth: OAuth2 — account ID + personal access token
Token management: id.getharvest.com/developers
Note

For Harvest: sign up at getharvest.com, configure projects/tasks/rates under Settings, enable API via OAuth2 (account ID + personal access token at id.getharvest.com/developers). Harvest's API base URL is https://api.harvestapp.io/v2/. BigTime offers bulk CSV import for staff, clients, and projects — prepare these CSVs during the discovery phase. Ensure the approval workflow matches the client's existing authority matrix. For DCAA-compliant clients, enable the 'Lock timesheets after approval' setting to prevent post-approval edits.

Step 4: Build the Core Calendar-to-Time-Entry Automation Flow

Create the primary automation workflow that reads calendar events from each employee's Outlook calendar, applies matching rules to identify billable client work, looks up the corresponding project code and billing rate, and creates a draft time entry in the PSA platform. This is the heart of the system. We build this in Power Automate (primary) with detailed alternative instructions for Zapier and n8n.

  • POWER AUTOMATE — Cloud Flow
  • Type: Scheduled cloud flow
  • Recurrence: Daily at 7:00 PM (after business hours, captures full day)

TRIGGER: Recurrence — Every 1 Day at 7:00 PM client timezone

STEP 1: Get all licensed users

  • Action: Office 365 Users — Search for users (V2)
  • Filter: accountEnabled eq true
  • Select: id, displayName, mail, jobTitle

STEP 2: Apply to each user

STEP 2a: Get calendar events for today

  • Action: Office 365 Outlook — Get events (V4)
  • Calendar: Calendar
  • User: current user email
  • Filter: start/dateTime ge 'YYYY-MM-DDT00:00:00' and end/dateTime le 'YYYY-MM-DDT23:59:59'
  • Select: subject, start, end, attendees, categories, bodyPreview, isAllDay

STEP 2b: Filter out non-work events

  • Skip if subject contains 'Personal' OR 'OOO' OR 'Lunch' OR 'Block'
  • Skip if isAllDay equals true (unless category = 'Travel')
  • Skip if duration < 15 minutes (skip quick reminders)
  • Skip if categories contains 'Non-Billable-Exclude'

STEP 2c: Apply to each qualifying event

STEP 2c-i: Match event to project

1
Check if event subject contains any known project code (regex match against project code list)
2
If no match, check attendee email domains against client domain lookup table
3
If no match, check event categories for client/project tags
4
If no match, flag as 'Unmatched — Manual Review Required'

STEP 2c-ii: Calculate duration

Power Automate expression
expression
# returns duration in minutes; divide by 60 for hours, round to nearest 0.1

div(sub(ticks(triggerBody()?['end']),ticks(triggerBody()?['start'])),600000000)

STEP 2c-iii: Look up billing rate

HTTP GET to BigTime API
http
# retrieve billing rate for staff member

GET https://iq.bigtime.net/BigtimeData/api/v2/staff/[staffId]/rates
X-Auth-Token: [API_KEY]
Content-Type: application/json

STEP 2c-iv: Create draft time entry

HTTP POST to BigTime API
http
# create draft time entry from matched calendar event

POST https://iq.bigtime.net/BigtimeData/api/v2/time
X-Auth-Token: [API_KEY]
Content-Type: application/json

{
  "Dt": "2025-07-15",
  "ProjectSID": "[matched_project_id]",
  "StaffSID": "[staff_id]",
  "Hours_Worked": 1.5,
  "TaskSID": "[task_id]",
  "Notes": "[Auto-generated] Meeting: [event_subject] with [attendee_names]",
  "BillRate": 175.00,
  "Billable": true,
  "DraftStatus": "DRAFT"
}

STEP 2d: Send daily summary email

  • Action: Office 365 Outlook — Send an email (V2)
  • To: current user email
  • Subject: 'Your Auto-Generated Time Entries for [date] — Review Required'
  • Body: HTML table listing all draft entries with Edit/Approve links to BigTime
Critical

CRITICAL COMPLIANCE NOTE: Entries MUST be created with DraftStatus=DRAFT (or equivalent unsubmitted status). The employee must review and approve/submit them personally. Auto-submitting without employee attestation violates FLSA and DCAA requirements. The matching logic in Step 2c-i is the most important component to customize per client. Start with simple subject-line keyword matching, then progressively add attendee domain matching and category-based matching. Maintain the lookup tables in a SharePoint list that the client can self-manage. For Zapier implementation: use a multi-step Zap with Schedule trigger → Google Calendar/Outlook trigger → Filter → Webhooks (POST to BigTime API). For n8n: use Cron node → Microsoft Outlook node → IF node → HTTP Request node.

Step 5: Build the Project Matching Lookup Tables in SharePoint

Create SharePoint lists that serve as the reference data for the automation's matching logic. These tables map calendar event attributes (keywords, attendee domains, categories) to PSA project codes and billing classifications. Storing these in SharePoint allows the client to maintain them without MSP involvement.

1
Create a SharePoint site for automation configuration — Site name: 'Time Automation Config', Site URL: https://[tenant].sharepoint.com/sites/TimeAutoConfig
2
Create LIST 1: ProjectKeywords — Columns: Keyword (Single line of text) e.g. 'ACME', 'Acme Corp', 'Project Phoenix'; ProjectCode (Single line of text) e.g. 'ACME-2025-01'; BigTimeProjectSID (Number) e.g. 12345; Billable (Yes/No) e.g. Yes; DefaultTaskSID (Number) e.g. 678
3
Create LIST 2: ClientDomains — Columns: Domain (Single line of text) e.g. 'acmecorp.com'; ClientName (Single line of text) e.g. 'Acme Corp'; DefaultProjectCode (Single line of text) e.g. 'ACME-2025-01'; BigTimeProjectSID (Number)
4
Create LIST 3: ExclusionPatterns — Columns: Pattern (Single line of text) e.g. 'Lunch', 'Personal', 'Doctor', '1:1 with'; ExclusionType (Choice: 'Skip Entirely' | 'Mark Non-Billable')
5
Create LIST 4: BillingRateOverrides — Columns: StaffEmail (Single line of text); ProjectCode (Single line of text); OverrideRate (Currency); EffectiveDate (Date)
6
Create LIST 5: AutomationLog — Columns: RunDate (Date/Time); UserEmail (Single line of text); EventSubject (Single line of text); MatchedProject (Single line of text); MatchMethod (Choice: 'Keyword' | 'Domain' | 'Category' | 'Unmatched'); EntryCreated (Yes/No); ErrorDetails (Multiple lines of text)
7
Populate initial data from the discovery phase project/client taxonomy
8
Grant the client's project champion Edit access to Lists 1–4
9
Grant all staff Read access to Lists 1–4
10
Grant only the automation service account Contribute access to List 5
Note

SharePoint lists are the recommended lookup mechanism because they are included in every M365 license, are easily maintained by non-technical client staff via browser, and have native Power Automate connectors. For Google Workspace clients, use Google Sheets as the equivalent lookup source. The AutomationLog list is critical for troubleshooting and compliance auditing. Set a retention policy of 3 years on this list. Consider creating a PowerBI dashboard connected to the AutomationLog for reporting on automation accuracy and match rates.

Step 6: Build the Expense Receipt Automation Flow

Create a secondary automation workflow that processes expense receipts captured via mobile photo, email forwarding, or scanner upload. The flow extracts vendor, amount, date, and category using the expense platform's built-in OCR (Ramp or Expensify), then matches the expense to the correct project and creates a draft expense entry in the PSA.

Option A: Ramp Setup and Configuration

1
Set up Ramp account at ramp.com
2
Issue physical/virtual corporate cards to employees
3
Configure expense categories in Ramp to match BigTime expense categories
4
Configure auto-categorization rules in Ramp: Ramp Dashboard > Settings > Accounting > Category Rules
5
Enable Ramp → BigTime sync using Power Automate with Ramp webhook + BigTime HTTP connector
Example Ramp auto-categorization rules
text
Example category rules:
Vendor contains 'Uber' or 'Lyft'         → Category: 'Travel - Ground Transport'
Vendor contains 'Marriott' or 'Hilton'   → Category: 'Travel - Lodging'

Option A: Power Automate Flow — Expense Receipt to PSA

Trigger: When an HTTP request is received (Ramp webhook on transaction.created)

1
Parse Ramp webhook JSON payload — Action: Parse JSON with schema: { transaction_id, amount, merchant_name, category, receipt_url, user_email, date }
2
Look up employee in BigTime by email
3
Match expense to project — Get items from SharePoint list 'ProjectKeywords', filter by keyword matching merchant_name or Ramp memo field. If no match: use employee's current default project or flag for manual assignment
4
Create draft expense entry in BigTime via HTTP POST
5
Notify employee — Send Teams adaptive card with expense summary and Approve / Edit / Reject buttons
Step 2: Look up employee in BigTime by email
http
GET https://iq.bigtime.net/BigtimeData/api/v2/staff?email=[user_email]
Step 4: Create draft expense entry in BigTime
http
POST https://iq.bigtime.net/BigtimeData/api/v2/expense

{
  "Dt": "[transaction_date]",
  "ProjectSID": [matched_project_id],
  "StaffSID": [staff_id],
  "Amount": [amount],
  "ExpenseTypeSID": [category_mapped_id],
  "Vendor": "[merchant_name]",
  "Notes": "[Auto-captured] [merchant_name] - $[amount]",
  "ReceiptURL": "[ramp_receipt_url]",
  "DraftStatus": "DRAFT"
}

Option B: Email-Based Receipt Capture Flow

Trigger: When a new email arrives in shared mailbox receipts@clientdomain.com

1
Extract attachment from email (receipt image or PDF)
2
Send attachment to Azure AI Document Intelligence (Form Recognizer) for OCR
3
Parse extracted fields: merchant, total, date
4
Match expense to project — same logic as Option A Step 3
5
Create draft expense entry and notify employee — same as Option A Steps 4 and 5
Step 2: Send receipt to Azure AI Document Intelligence for OCR
http
POST https://[resource].cognitiveservices.azure.com/formrecognizer/documentModels/prebuilt-receipt:analyze
Note

Ramp is recommended because it combines corporate card issuance with automatic receipt matching and OCR at no cost on the free tier — eliminating a separate OCR step. For clients who cannot or will not use Ramp, Expensify ($5/user/month) provides similar OCR and categorization capabilities. The email-based approach (Option B) requires Azure AI Document Intelligence at $1.50 per 1,000 pages (prebuilt receipt model) — very cost-effective for typical volumes. All expense entries must also be created as DRAFT status requiring employee review and manager approval.

Step 7: Configure Notification and Approval Workflows

Set up the daily digest email and Teams notifications that present auto-generated time and expense entries to employees for review and attestation. Configure the multi-level approval chain in the PSA platform. This step is critical for compliance — employees must actively confirm their time entries.

Daily Digest Email

Appended to the main calendar-to-time flow (Step 2d). Configure a Power Automate Send Email action with the following HTML template:

HTML email body template for the daily digest Power Automate Send Email action
html
<!-- Subject: ⏱️ Your Time Entries for @{formatDateTime(utcNow(),'MMMM d, yyyy')} — Review Required -->
<html><body>
<h2>Auto-Generated Time Entries</h2>
<p>The following entries were created from your calendar. Please review and submit by EOD tomorrow.</p>
<table border='1' cellpadding='8' style='border-collapse:collapse;'>
<tr style='background:#4472C4;color:white;'>
  <th>Time</th><th>Duration</th><th>Project</th><th>Description</th><th>Billable</th><th>Action</th>
</tr>
<!-- Dynamic rows from Apply to Each -->
<tr>
  <td>9:00-10:30 AM</td><td>1.5 hrs</td><td>ACME-2025-01</td>
  <td>Meeting: Q1 Strategy Review with Acme Corp</td><td>✅ Yes</td>
  <td><a href='https://app.bigtime.net/time/edit/[entryId]'>Edit</a></td>
</tr>
</table>
<p><strong>⚠️ Unmatched Events (action required):</strong></p>
<!-- List events that couldn't be auto-matched -->
<p><a href='https://app.bigtime.net/time'>Open BigTime to Review All Entries</a></p>
<p style='color:gray;font-size:11px;'>This is an automated message. Entries are in DRAFT status until you submit them.</p>
</body></html>

Teams Adaptive Card Notification

Alternative or supplement to the email digest. Use the Power Automate action "Post adaptive card in a chat or channel (V2)" with the following card JSON:

Teams Adaptive Card JSON payload for Power Automate "Post adaptive card" action
json
{
  "type": "AdaptiveCard",
  "version": "1.4",
  "body": [
    {"type":"TextBlock","text":"⏱️ Time Entry Review","weight":"Bolder","size":"Medium"},
    {"type":"TextBlock","text":"You have @{length(body('Filter_qualified_events'))} draft entries for today.","wrap":true},
    {"type":"FactSet","facts":[
      {"title":"Total Hours","value":"@{variables('totalHours')} hrs"},
      {"title":"Billable","value":"@{variables('billableHours')} hrs"},
      {"title":"Unmatched","value":"@{variables('unmatchedCount')} events"}
    ]}
  ],
  "actions": [
    {"type":"Action.OpenUrl","title":"Review in BigTime","url":"https://app.bigtime.net/time"},
    {"type":"Action.OpenUrl","title":"Report Issue","url":"mailto:msp-support@mspdomain.com?subject=Time%20Automation%20Issue"}
  ]
}

BigTime Approval Workflow Configuration

Navigate to Admin > Approval Settings in BigTime and apply the following configuration for both time and expense entries:

  • Time Entries — Auto-route to: Direct Manager (from Staff record)
  • Time Entries — Escalation: If not approved within 48 hours, escalate to Controller
  • Time Entries — Lock on approval: YES (entries cannot be edited after approval)
  • Time Entries — Require notes for edits to auto-generated entries: YES
  • Expense Entries — Route to: Direct Manager for < $500
  • Expense Entries — Route to: Controller for >= $500
  • Expense Entries — Receipt required: YES for entries > $25
  • Expense Entries — Lock on approval: YES
Note

The daily digest email is the primary compliance mechanism. It serves as the employee's opportunity to review, correct, and attest to their time. Send it at end of business day (7 PM) so employees can review the next morning with fresh eyes. For firms under DCAA compliance, consider sending the notification twice: once at end of day (for same-day review) and a reminder the next morning. Track email open rates via Power Automate's email tracking or a simple read-receipt flag. If an employee hasn't submitted their draft entries within 48 hours, send an escalation to their manager.

Step 8: Build the Weekly Unmatched Events Report and Manager Dashboard

Create a weekly summary flow that identifies patterns in unmatched events (events that couldn't be auto-assigned to a project) and sends a report to the operations manager. Also create a Power BI or Excel dashboard showing automation accuracy metrics. This drives continuous improvement of the matching rules.

Weekly Report Flow

1
Trigger: Recurrence — Every Monday at 8:00 AM
2
Query AutomationLog SharePoint list — Action: Get items — Filter: RunDate ge '[last Monday]' and RunDate le '[last Sunday]'
3
Calculate metrics (see expressions below)
4
Get top unmatched patterns — Group unmatched events by subject keyword (first 3 words) to identify recurring patterns
5
Send report to operations manager — Email with metrics summary and top unmatched patterns. Include recommendation: 'Add keyword [X] to ProjectKeywords list mapped to project [Y]'
Compose expressions for: Total events processed, Matched events, Match rate, Unmatched events, Errors
plaintext
@{length(body('Get_items')?['value'])}
@{length(filter(body('Get_items')?['value'], item()?['MatchMethod'] ne 'Unmatched'))}
@{div(mul(variables('matchedCount'),100),variables('totalCount'))}%
@{length(filter(body('Get_items')?['value'], item()?['MatchMethod'] eq 'Unmatched'))}
@{length(filter(body('Get_items')?['value'], item()?['EntryCreated'] eq false))}
1
Connect to SharePoint list 'AutomationLog' via Power BI SharePoint connector
2
Visual 1: Match Rate trend — line chart by week
3
Visual 2: Match Method breakdown — pie chart (Keyword vs Domain vs Category vs Unmatched)
4
Visual 3: Hours auto-captured vs total billable hours — bar chart by employee
5
Visual 4: Top 10 unmatched event subjects — table
6
Visual 5: Error rate trend — line chart
7
Refresh: Daily
8
Publish to Power BI workspace shared with client leadership
Note

Target KPI: 85%+ match rate within 4 weeks of go-live, 95%+ by week 8. The weekly report drives a continuous improvement loop: as the operations manager adds keywords and domain mappings based on unmatched patterns, the match rate increases. This report is also the MSP's proof of value for monthly managed service billing. If Power BI is not licensed, create an equivalent Excel dashboard using Power Query to pull from the SharePoint list, hosted in SharePoint and auto-refreshed.

Step 9: Pilot Deployment with Test Group

Deploy the complete automation to a pilot group of 3–5 employees representing different roles (partner, senior consultant, junior staff, admin) for a 1-week parallel run. During this period, employees continue their normal time entry process AND receive auto-generated entries, allowing side-by-side comparison for accuracy validation.

1
Select pilot users (3-5 people across different roles)
2
Configure the Power Automate flow to only process pilot user calendars: Add a condition at Step 2: user email IN ('partner@client.com','senior@client.com','junior@client.com')
3
Enable the flow and monitor for 5 business days
4
Daily accuracy check during pilot: For each pilot user, compare: a) Auto-generated draft entries (from automation) vs. b) Manually entered time (from their normal process). Calculate: precision (% of auto entries that are correct) and recall (% of actual time captured)
5
Document discrepancies in a shared Excel tracker with columns: Date | User | Event Subject | Auto Entry | Manual Entry | Match? | Issue — Use this to refine matching rules, exclusion patterns, and duration calculations
6
Pilot exit criteria (ALL must be met): Match rate >= 80% (events correctly assigned to projects), Precision >= 90% (auto-generated entries that are accurate), No duplicate entries created, No personal events leaking into time entries, Daily digest emails delivered successfully to all pilot users, Approval workflow functioning correctly in BigTime, No API errors in AutomationLog for 3 consecutive days
Note

The pilot phase is non-negotiable. Even with perfect configuration, real-world calendar data will surface edge cases: recurring meetings with no subject, external invites from personal Gmail accounts, all-day 'Focus Time' blocks, canceled meetings that remain on the calendar, etc. Expect to make 10–20 adjustments to matching rules and exclusion patterns during the pilot. Common pilot issues: time zone mismatches (events in UTC vs. local), duplicate entries from recurring series vs. single occurrences, and meetings that span the midnight boundary.

Step 10: Full Rollout, User Training, and Legacy System Cutover

After successful pilot, expand the automation to all employees. Conduct group training sessions on the new workflow (reviewing auto-generated entries, submitting time, capturing expenses). Switch the legacy time entry system to read-only mode. Monitor closely for the first 2 weeks.

1
Remove pilot user filter from Power Automate flow to process all users
2
Ensure all staff are provisioned in BigTime with correct: Roles and billing rates, Manager assignments (for approval routing), Project assignments
3
Send company-wide announcement email from the managing partner (not the MSP): Subject: 'New Automated Time Tracking — Starting [Date]' — Content: What's changing, why, what employees need to do (review daily digest, submit entries)
4
Conduct training sessions (recommended: 2 sessions, 30 min each): Session 1: All Staff (30 min) — Demo the daily digest email, how to review and edit draft entries in BigTime, how to submit time entries, how to capture expense receipts (Ramp app or email forwarding), calendar hygiene best practices (include client name in meeting subject), Q&A. Session 2: Managers & Approvers (30 min) — Approval workflow demo, how to handle unmatched entries, how to add new project keywords to SharePoint lists, dashboard overview, escalation path for issues
5
Set legacy system to read-only: Keep accessible for 90 days for historical reference, then archive
6
Enable 'go-live monitoring' Power Automate flow: Additional flow that runs daily and alerts the MSP if: Flow execution failures > 0, match rate drops below 80%, any user hasn't submitted time in 3+ days, API rate limit warnings from BigTime or Graph API
Note

Schedule rollout for a Monday to capture a full work week. Avoid rollout during month-end close, tax season (for accounting firms), or major project deadlines. The managing partner's sponsorship email is critical for adoption — employees respond to leadership endorsement, not IT announcements. Record the training sessions and upload to SharePoint for future new-hire onboarding. Plan for a 2-week 'hypercare' period where the MSP provides same-day response to any issues.

Step 11: Connect Downstream Accounting Sync

Activate the PSA-to-accounting integration so that approved time entries generate invoices and approved expenses flow into the general ledger. This completes the end-to-end automation from calendar event to client invoice.

BigTime → QuickBooks Online Sync Configuration

1
In BigTime: Settings > Integrations > QuickBooks Online
2
Click 'Connect to QuickBooks' and authorize via OAuth
3
Map BigTime entities to QBO entities: BigTime Clients → QBO Customers, BigTime Expense Categories → QBO Expense Accounts, BigTime Invoice Templates → QBO Invoice Templates, BigTime Payment Terms → QBO Payment Terms
4
Configure sync settings: Sync approved time entries as invoice line items: YES, Sync approved expenses as bill line items: YES, Sync frequency: Daily at 2:00 AM, Conflict resolution: BigTime is source of truth
5
Run initial sync test
6
For Xero integration (alternative): BigTime > Settings > Integrations > Xero — Similar OAuth authorization and entity mapping
7
Validate financial accuracy: Billable hours × rate = correct invoice amount, Expense amounts match to the penny, Tax calculations are correct, Client/project allocations are accurate

Initial Sync Test

1
Create a test time entry and expense in BigTime
2
Approve through full workflow
3
Trigger manual sync
4
Verify entry appears correctly in QBO

Xero API Endpoint (Alternative Integration)

Xero API base URL for BigTime integration
text
https://api.xero.com/api.xro/2.0/
Note

The accounting sync should only be activated AFTER the pilot confirms data accuracy. Run a parallel check for the first billing cycle: compare auto-generated invoices against what the firm would have created manually. Common issues: duplicate customers in QBO (requires deduplication before mapping), expense category mismatches (BigTime has different categories than QBO chart of accounts), and tax handling differences between platforms. For firms on Xero, the same general approach applies — BigTime and Harvest both have native Xero integrations.

Custom AI Components

Calendar Event Project Matcher

Type: workflow

The core deterministic matching engine that takes a calendar event and returns the best-matching project code from the PSA system. Uses a three-tier cascading match strategy: (1) keyword matching against event subject line, (2) attendee email domain matching against client domains, (3) Outlook category/tag matching. Falls back to 'Unmatched' status if no match found. This is not ML-based — it is pure rules-based deterministic logic, which is appropriate for the accuracy and auditability requirements of professional services time tracking.

Implementation:

Calendar Event Project Matcher — Power Automate Implementation

Architecture

This component is implemented as a Power Automate Child Flow (called from the main daily processing flow) that accepts a calendar event as input and returns a matched project.

Input Schema

json
{
  "eventSubject": "Q1 Strategy Review with Acme Corp",
  "eventAttendees": ["jdoe@acmecorp.com", "msmith@clientfirm.com"],
  "eventCategories": ["ACME-2025-01"],
  "eventStart": "2025-07-15T09:00:00",
  "eventEnd": "2025-07-15T10:30:00",
  "employeeEmail": "consultant@clientfirm.com"
}

Output Schema

json
{
  "matched": true,
  "matchMethod": "Keyword",
  "projectCode": "ACME-2025-01",
  "bigTimeProjectSID": 12345,
  "bigTimeTaskSID": 678,
  "billable": true,
  "durationHours": 1.5,
  "confidence": "High",
  "notes": "Matched on keyword 'Acme Corp' in subject"
}

Step-by-Step Flow Logic

Step 1: Check Exclusion Patterns

  • Action: Get items from SharePoint list ExclusionPatterns
  • For each pattern, check if eventSubject contains the pattern (case-insensitive)
  • If match found and ExclusionType = 'Skip Entirely': Return { matched: false, matchMethod: 'Excluded' }
  • If match found and ExclusionType = 'Mark Non-Billable': Set variable forcedNonBillable = true

Step 2: Tier 1 — Subject Keyword Match

  • Action: Get all items from SharePoint list ProjectKeywords
  • Action: Apply to each keyword record

Condition to evaluate for each keyword record:

Tier 1 keyword match condition
powerautomate
contains(toLower(triggerBody()?['eventSubject']), toLower(items('Apply_to_each')?['Keyword']))

If TRUE, set the following match variables:

Variables to set on Tier 1 match
powerautomate
matchFound = true
matchMethod = 'Keyword'
projectCode = items('Apply_to_each')?['ProjectCode']
bigTimeProjectSID = items('Apply_to_each')?['BigTimeProjectSID']
bigTimeTaskSID = items('Apply_to_each')?['DefaultTaskSID']
billable = items('Apply_to_each')?['Billable']
confidence = 'High'
Note

Process keywords from longest to shortest to avoid false matches (e.g., 'Acme Corp Advisory' before 'Acme').

Step 3: Tier 2 — Attendee Domain Match (only if Tier 1 didn't match)

  • Condition: matchFound equals false
  • Action: Get all items from SharePoint list ClientDomains
  • For each attendee email in eventAttendees: Extract domain using split(items('Apply_to_each_attendee'), '@')[1]
  • Skip if domain equals employee's own domain
  • Check if domain exists in ClientDomains list

If TRUE, set the following match variables:

Variables to set on Tier 2 domain match
powerautomate
matchFound = true
matchMethod = 'Domain'
projectCode = items('Domain_lookup')?['DefaultProjectCode']
confidence = 'Medium'
Note

If multiple external domains are found, use the first non-employee domain. Most calendar events have one external client domain.

Step 4: Tier 3 — Category/Tag Match (only if Tier 1 and 2 didn't match)

  • Condition: matchFound equals false
  • Check if eventCategories contains any value matching a project code pattern (regex: [A-Z]+-\d{4}-\d+)
  • If TRUE: Look up the category value in ProjectKeywords list
  • Set match with confidence = 'High' (explicit tag is reliable)

Step 5: Calculate Duration

Rounds to nearest 0.1 hour (6-minute increments), standard for professional services
powerautomate
durationMinutes = div(sub(ticks(triggerBody()?['eventEnd']), ticks(triggerBody()?['eventStart'])), 600000000)
durationHours = div(durationMinutes, 60.0)
roundedHours = div(round(mul(durationHours, 10)), 10.0)

Step 6: Apply Non-Billable Override

  • If forcedNonBillable = true: Set billable = false

Step 7: Return Result

  • Action: Respond to a PowerApp or flow
  • Return the output JSON schema

Matching Priority Table

Expense Receipt Categorizer

Type: integration An integration component that receives expense transaction data from Ramp (via webhook) or processes receipt images via Azure AI Document Intelligence, extracts key fields (vendor, amount, date, category), and maps the transaction to the correct PSA project and expense category. For Ramp-sourced transactions, the categorization is already done by Ramp's AI; this component handles the PSA mapping. For receipt images, it adds OCR extraction.

Ramp Webhook Setup

1
In Ramp Dashboard: Settings > Developer > Webhooks
2
Add webhook URL: https://[your-logic-app-or-power-automate-url]
3
Events to subscribe: transaction.created, transaction.updated

Power Automate Flow

Trigger: When an HTTP request is received Method: POST

Request body JSON schema
json
{
  "type": "object",
  "properties": {
    "event_type": {"type": "string"},
    "data": {
      "type": "object",
      "properties": {
        "id": {"type": "string"},
        "amount": {"type": "number"},
        "merchant_name": {"type": "string"},
        "merchant_category_code": {"type": "string"},
        "category": {"type": "string"},
        "memo": {"type": "string"},
        "user_email": {"type": "string"},
        "date": {"type": "string"},
        "receipt_urls": {"type": "array", "items": {"type": "string"}}
      }
    }
  }
}
1
Validate webhook signature (Ramp HMAC-SHA256)
2
Map Ramp category to BigTime ExpenseTypeSID using Category Mapping Table (SharePoint list 'ExpenseCategoryMap') — see table below
3
Look up employee's active project (use same domain/keyword matching as time entries, or default to employee's primary project assignment)
4
POST to BigTime Expense API
5
Attach receipt image if available
Step 4: POST to BigTime Expense API
http
POST https://iq.bigtime.net/BigtimeData/api/v2/expense
Headers:
  X-Auth-Token: [API_KEY]
  Content-Type: application/json
Body:
{
  "Dt": "[transaction_date]",
  "ProjectSID": [matched_project_sid],
  "StaffSID": [staff_sid],
  "Amount": [amount],
  "ExpenseTypeSID": [mapped_expense_type],
  "Vendor": "[merchant_name]",
  "Notes": "[Auto-captured from Ramp] [merchant_name] - [memo]",
  "Billable": true,
  "DraftStatus": "DRAFT"
}
Step 5: Attach receipt image if available
http
POST https://iq.bigtime.net/BigtimeData/api/v2/expense/[expenseId]/receipt
Headers:
  X-Auth-Token: [API_KEY]
  Content-Type: multipart/form-data
Body: [receipt_image_binary from receipt_urls[0]]

Option B: Email/Scanner Receipt OCR (Azure AI Document Intelligence)

For clients not using Ramp.

Trigger: When a new email arrives in shared mailbox receipts@clientdomain.com OR: When a file is created in SharePoint folder Receipts/Inbox

1
Extract attachment (image or PDF)
2
Call Azure AI Document Intelligence
3
Poll for results
4
Parse extracted fields
5
Apply same category mapping as Option A
6
POST to BigTime as in Option A
Step 2: Call Azure AI Document Intelligence
http
POST https://[resource-name].cognitiveservices.azure.com/formrecognizer/documentModels/prebuilt-receipt:analyze?api-version=2023-07-31
Headers:
  Ocp-Apim-Subscription-Key: [subscription_key]
  Content-Type: application/octet-stream
Body: [binary image/PDF data]
Step 3: Poll for results
http
GET https://[resource-name].cognitiveservices.azure.com/formrecognizer/documentModels/prebuilt-receipt/analyzeResults/[resultId]?api-version=2023-07-31
Step 4: Example parsed extracted fields
json
{
  "MerchantName": "Marriott Downtown",
  "Total": 289.50,
  "TransactionDate": "2025-07-14",
  "Items": [
    {"Description": "Room - King Suite", "Amount": 249.00},
    {"Description": "Tax", "Amount": 40.50}
  ]
}
Note

Azure AI Document Intelligence pricing: $1.50 per 1,000 pages (prebuilt receipt model). Typical firm: 50–200 receipts/month = $0.08–$0.30/month.

Timesheet Completeness Monitor

Type: workflow A monitoring workflow that runs daily at 9 AM and checks whether all employees have reviewed and submitted their auto-generated time entries from the previous day. Sends escalation notifications to managers for employees who have unsubmitted draft entries older than 24 hours. Generates a weekly compliance scorecard showing submission rates by employee and department. This component ensures the automation achieves its ROI by driving employee adoption and compliance.

Flow 1: Daily Submission Check (runs at 9:00 AM)

Trigger: Recurrence — Daily at 9:00 AM

1
Get all active staff from BigTime
2
For each staff member, get yesterday's time entries
3
Check entry statuses
4
Send reminders based on status
5
If draft entries are > 48 hours old, escalate to manager
Step 1: Get all active staff from BigTime
http
GET https://iq.bigtime.net/BigtimeData/api/v2/staff?IsActive=true
Headers: X-Auth-Token: [API_KEY]
Step 2: Get yesterday's time entries for each staff member
http
GET https://iq.bigtime.net/BigtimeData/api/v2/time?StaffSID=[sid]&StartDt=[yesterday]&EndDt=[yesterday]
Headers: X-Auth-Token: [API_KEY]
Step 3: Check entry statuses and assign compliance status
plaintext
For each entry in response:
  If DraftStatus == 'DRAFT':
    Add to draftEntries collection
  If DraftStatus == 'SUBMITTED' or 'APPROVED':
    Add to submittedEntries collection

If count(submittedEntries) == 0 AND count(draftEntries) > 0:
  status = 'HAS_UNSUBMITTED_DRAFTS'
Else If count(submittedEntries) == 0 AND count(draftEntries) == 0:
  status = 'NO_ENTRIES' (possible missed day)
Else:
  status = 'COMPLIANT'

Step 4: Send reminders based on status

  • For HAS_UNSUBMITTED_DRAFTS: Send Teams message to employee — "⏰ Reminder: You have [X] draft time entries from yesterday that need your review and submission. [Link to BigTime]"
  • For NO_ENTRIES (and it was a business day): Send Teams message to employee — "📋 No time entries found for yesterday. Did you have meetings or project work? Please log your time. [Link to BigTime]"
Step 5: Fetch overdue draft entries (> 48 hours old) for escalation check
http
GET https://iq.bigtime.net/BigtimeData/api/v2/time?StaffSID=[sid]&DraftStatus=DRAFT&EndDt=[2 days ago]

Step 5 (continued): If count > 0, get manager email from staff record and send escalation email: - Subject: ⚠️ Overdue Time Entries: [Employee Name] - Body: [Employee] has [X] draft time entries from [dates] that have not been submitted. Please follow up.

Flow 2: Weekly Compliance Scorecard (runs Monday at 8:30 AM)

Trigger: Recurrence — Weekly on Monday at 8:30 AM

Step 1: Calculate weekly compliance metrics per staff member
plaintext
totalDraftEntries = count of entries with DraftStatus='DRAFT' for prior week
totalSubmittedEntries = count of entries with DraftStatus='SUBMITTED' or 'APPROVED'
totalHoursLogged = sum of Hours_Worked for all submitted entries
targetHours = 40 (configurable per employee; part-time may differ)
completionRate = totalHoursLogged / targetHours * 100
autoMatchRate = count of entries with Notes containing '[Auto-generated]' / totalSubmittedEntries * 100

Step 2: Compile scorecard and send to operations manager as an HTML email with a sortable table. Color coding: Green = Completion ≥ 90%, Yellow = Completion 70–89%, Red = Completion < 70%.

  • Table columns: Employee | Hours Logged | Target | Completion % | Auto-Match % | Overdue Drafts
  • Example row: J. Smith | 38.5 | 40 | 96% | 92% | 0
  • Example row: M. Jones | 22.0 | 40 | 55% | 85% | 8
Step 3: Log weekly metrics to SharePoint for Power BI dashboard trend analysis
plaintext
SharePoint List: WeeklyComplianceLog
Columns: WeekEnding, StaffEmail, HoursLogged, TargetHours, CompletionPct, AutoMatchPct, OverdueDrafts

Configuration Variables

Stored in SharePoint list 'MonitorConfig'.

  • ReminderDelayHours (Default: 24) — Hours before first reminder is sent
  • EscalationDelayHours (Default: 48) — Hours before manager escalation is triggered
  • TargetHoursDefault (Default: 40) — Default weekly target hours per employee
  • BusinessDays (Default: Mon–Fri) — Days to check for time entries
  • SkipHolidays (Default: true) — Whether to reference the holiday calendar before sending reminders
  • HolidayCalendarId (Default: [calendar_id]) — M365 holiday calendar to reference

Calendar Hygiene Advisor

Type: workflow A weekly analysis workflow that evaluates each employee's calendar event quality and provides personalized recommendations for improving event naming, tagging, and categorization to increase the automation's match rate. Sends a friendly, non-intrusive tip email to employees whose events frequently fail to match. This drives organic improvement in data quality without requiring enforcement policies.

Implementation

Trigger: Recurrence — Weekly on Friday at 3:00 PM

Step 1: Calculate per-user match rates from AutomationLog

For each active staff member, query AutomationLog (SharePoint) for the current week:

SharePoint AutomationLog query and match rate calculation
text
Filter: RunDate ge [Monday] AND RunDate le [Friday] AND UserEmail eq [email]

totalEvents = count of all records
matchedEvents = count where MatchMethod ne 'Unmatched'
unmatchedEvents = count where MatchMethod eq 'Unmatched'
matchRate = matchedEvents / totalEvents * 100

Step 2: Identify improvement opportunities

For users with matchRate < 85%, retrieve their unmatched events and analyze patterns by issue type:

  • Issue Type 1 — Vague subjects: Detect: subject length < 10 characters OR subject in ('Meeting', 'Call', 'Catch up', 'Sync', 'Chat'). Tip: 'Include the client or project name in your meeting title. Instead of "Meeting", try "Acme Corp Q1 Review"'
  • Issue Type 2 — Missing client identifier: Detect: No external attendees AND no keyword match AND no category. Tip: 'Add the Outlook category for your project (e.g., ACME-2025-01) to internal working sessions'
  • Issue Type 3 — Personal events not excluded: Detect: Events matched exclusion pattern but were only caught after processing. Tip: 'Mark personal appointments with the category "Personal" so they are automatically skipped'
  • Issue Type 4 — Could be auto-matched with a new keyword: Detect: 3+ unmatched events share a common word not in ProjectKeywords. Action: Suggest adding the keyword to the ops manager. Tip to user: 'We noticed several meetings mentioning "Phoenix" — we're adding this as a recognized project keyword'

Step 3: Send personalized tip email (only to users below 85% match rate)

Personalized tip email template sent to users below 85% match rate
text
Subject: 💡 Quick Tip to Improve Your Auto-Time Tracking
Body:
Hi [FirstName],

Your auto-time tracking matched [matchRate]% of your calendar events this week ([matchedEvents] of [totalEvents]).

Here's a quick tip to improve it:

[personalized tip based on most common issue type]

This small change will save you [estimated minutes] of manual time entry each week.

Your top unmatched events this week:
- [Event 1 subject] ([date])
- [Event 2 subject] ([date])
- [Event 3 subject] ([date])

Need help? Reply to this email or reach out to [operations manager name].

Happy tracking! 🎯
—Time Automation System

(P.S. Your match rate last week was [lastWeekRate]% — [improving/declining] trend)

Step 4: Send ops manager summary of suggested keyword additions

Weekly ops manager summary email with keyword suggestions and firm-wide match rate stats
text
Subject: 📊 Weekly Calendar Hygiene Report — Keyword Suggestions
Body:
Based on this week's unmatched events, consider adding these keywords:

| Keyword  | Suggested Project | Frequency | Users Affected |
|----------|------------------|-----------|----------------|
| Phoenix  | TBD              | 12 events | 4 users        |
| Retainer | ACME-2025-RET    | 8 events  | 3 users        |

Overall firm match rate: [firmMatchRate]% (target: 95%)
Top performers: [user1] (98%), [user2] (97%)
Needs attention: [user3] (62%), [user4] (71%)

Design Principles

  • Never send more than 1 tip email per user per week (avoid notification fatigue)
  • Only send if match rate is below 85% (don't nag high performers)
  • Tone is helpful and encouraging, never punitive
  • Include the improving/declining trend to gamify improvement
  • Ops manager gets the keyword suggestions to maintain the lookup tables

Testing & Validation

  • UNIT TEST 1 — Calendar API Connection: Manually trigger the Power Automate flow for a single test user. Verify that the flow successfully retrieves today's calendar events from Microsoft Graph API. Check that event subject, start/end times, attendees, and categories are all correctly parsed. Expected: All calendar events for the test user are returned with complete metadata.
  • UNIT TEST 2 — Exclusion Pattern Filtering: Create test calendar events with known exclusion keywords ('Lunch with team', 'Personal - Doctor appointment', 'OOO - Vacation'). Run the flow. Verify that all exclusion-pattern events are correctly filtered out and no time entries are created for them. Expected: Zero draft entries for excluded events; events logged in AutomationLog with MatchMethod='Excluded'.
  • UNIT TEST 3 — Tier 1 Keyword Matching: Create a calendar event with subject 'ACME Corp Advisory Meeting' where 'ACME' is a configured keyword in the ProjectKeywords SharePoint list mapped to project ACME-2025-01. Run the flow. Expected: Draft time entry created in BigTime with ProjectSID matching ACME-2025-01, MatchMethod='Keyword', confidence='High'.
  • UNIT TEST 4 — Tier 2 Domain Matching: Create a calendar event with subject 'Strategy Discussion' (no keywords) with an external attendee jdoe@acmecorp.com, where acmecorp.com is in the ClientDomains SharePoint list. Run the flow. Expected: Draft entry created with the default project for Acme Corp, MatchMethod='Domain', confidence='Medium'.
  • UNIT TEST 5 — Tier 3 Category Matching: Create a calendar event with subject 'Working Session' (no keywords, no external attendees) but assign Outlook category 'ACME-2025-01'. Run the flow. Expected: Draft entry created with correct project, MatchMethod='Category', confidence='High'.
  • UNIT TEST 6 — Unmatched Event Handling: Create a calendar event with subject 'Quick sync' with only internal attendees and no categories. Run the flow. Expected: No draft entry created in BigTime; event logged in AutomationLog with MatchMethod='Unmatched'; event appears in daily digest email under 'Unmatched Events' section.
  • UNIT TEST 7 — Duration Calculation Accuracy: Create calendar events of exactly 30 minutes, 1 hour, 1 hour 45 minutes, and 2 hours 15 minutes. Run the flow. Expected: Draft entries with Hours_Worked of 0.5, 1.0, 1.8, and 2.3 respectively (rounded to nearest 0.1 hour).
  • UNIT TEST 8 — Draft Status Compliance: Run the flow and verify that ALL auto-generated entries in BigTime have DraftStatus='DRAFT' (not 'SUBMITTED' or 'APPROVED'). This is a critical compliance check. Expected: 100% of auto-generated entries are in DRAFT status.
  • INTEGRATION TEST 1 — Daily Digest Email: Run the full flow for a test user with 5 calendar events (3 matched, 1 non-billable, 1 unmatched). Verify the daily digest email is received within 5 minutes, contains an HTML table with all 5 events correctly categorized, includes working Edit links to BigTime, and lists the unmatched event separately.
  • INTEGRATION TEST 2 — Expense Receipt Flow (Ramp): Make a test purchase on a Ramp corporate card. Verify that within 15 minutes: (a) the Ramp webhook fires, (b) Power Automate processes the transaction, (c) a draft expense entry appears in BigTime with correct amount, vendor, and category, (d) the employee receives a Teams notification.
  • INTEGRATION TEST 3 — Expense Receipt Flow (Email OCR): Email a photo of a receipt to the shared receipts@clientdomain.com mailbox. Verify that Azure AI Document Intelligence correctly extracts merchant name, total amount, and date. Verify a draft expense entry is created in BigTime within 10 minutes.
  • INTEGRATION TEST 4 — Approval Workflow: Submit a draft time entry in BigTime as a test employee. Verify the entry routes to the correct manager for approval. Approve the entry. Verify it moves to 'APPROVED' status and the entry is locked from further editing.
  • INTEGRATION TEST 5 — BigTime to QuickBooks Sync: Create and approve a time entry and an expense entry in BigTime. Trigger the QBO sync. Verify: (a) the time entry appears as an invoice line item in QBO with correct client, hours, rate, and amount, (b) the expense appears in QBO with correct vendor, amount, and GL account mapping.
  • INTEGRATION TEST 6 — Completeness Monitor: Leave 3 draft entries unsubmitted for 24+ hours for a test user. Verify the Completeness Monitor flow sends a reminder to the test user. Leave them unsubmitted for 48+ hours and verify escalation email is sent to the test user's manager.
  • END-TO-END TEST — Full Day Simulation: For one pilot user, let the system run naturally for a full business day with real meetings. At end of day, compare: (a) auto-generated draft entries vs. (b) what the user would have manually entered. Calculate precision (correct entries / total auto entries) and recall (auto-captured hours / total actual hours). Target: Precision >= 90%, Recall >= 80%.
  • LOAD TEST — Multi-User Processing: Run the flow for all 25 users simultaneously. Verify: (a) all users' events are processed within 30 minutes, (b) no API rate limit errors from Microsoft Graph or BigTime, (c) no duplicate entries created, (d) AutomationLog captures all processing results.
  • SECURITY TEST — Personal Event Privacy: Create calendar events marked 'Private' in Outlook for a test user. Verify the automation does NOT read the event body or attendee list for private events. Verify private events are excluded from processing. This validates GDPR/privacy compliance.
  • FAILURE RECOVERY TEST — API Outage Simulation: Temporarily invalidate the BigTime API key. Run the flow. Verify: (a) the flow logs errors to AutomationLog, (b) the MSP receives an alert notification, (c) events are queued for retry, (d) no data is lost, (e) the flow recovers cleanly when the API key is restored.

Client Handoff

Client Handoff Checklist

Training Sessions Delivered

1
All-Staff Training (30 min, recorded): How to review daily digest emails, edit draft time entries in BigTime, submit timesheets, capture expense receipts via Ramp app or email forwarding, and calendar hygiene best practices (including client names in meeting subjects, using Outlook categories)
2
Manager/Approver Training (30 min, recorded): How to approve/reject time and expense entries, interpret the weekly compliance scorecard, handle unmatched entries, and escalation procedures
3
Operations Manager/Admin Training (45 min, recorded): How to maintain SharePoint lookup tables (ProjectKeywords, ClientDomains, ExclusionPatterns), add new clients/projects, read the Power BI dashboard, and when to contact the MSP

Documentation Delivered

  • User Quick Reference Guide (2-page PDF): Step-by-step screenshots for reviewing and submitting auto-generated time entries; expense receipt capture; calendar hygiene tips
  • Admin Operations Manual (10-page document): SharePoint list maintenance procedures, new project/client onboarding checklist, troubleshooting guide for common issues (unmatched events, duplicate entries, API errors), Power Automate flow architecture diagram
  • Compliance Documentation: Audit trail access procedures, data retention policy configuration, FLSA/DCAA compliance design decisions and how they're enforced in the system
  • Architecture Diagram: Visual diagram of all data flows, API connections, and platform relationships, stored in the client's SharePoint
  • Credential & Configuration Register: All API keys, app registration details, service accounts, and configuration settings documented in IT Glue (or equivalent) with the MSP retaining a copy

Success Criteria Review (conducted in Week 6 handoff meeting)

Transition to Managed Services

  • Handoff meeting with client stakeholders to review all success criteria
  • Transition from 'implementation hypercare' (same-day response) to ongoing managed service SLA (4-hour response for critical, next-business-day for standard)
  • Schedule first quarterly optimization review for 90 days post-go-live
  • Provide MSP support contact information and escalation matrix

Maintenance

Ongoing Maintenance Responsibilities

Daily Monitoring (Automated — 5 min MSP review)

  • Power Automate flow run history: Check for failed runs via the Power Automate admin center or a monitoring flow that alerts the MSP on any failure. Target: 0 failures per day.
  • API health: Monitor Microsoft Graph API and BigTime API response times and error rates via the AutomationLog SharePoint list.
  • Automated alert triggers: The monitoring flow sends Teams/email alerts to the MSP's NOC or dedicated technician for: flow execution failures, API authentication errors (expired tokens/keys), match rate dropping below 75% for any user, BigTime-to-QBO sync failures.

Weekly Tasks (15–30 min MSP effort)

  • Review the weekly compliance scorecard: Identify users consistently below 80% submission rate; coordinate with client operations manager on follow-up.
  • Review the unmatched events report: Propose new keywords or domain mappings to the client operations manager. Target: improve match rate by 1–2% per week until reaching 95%+.
  • Check Power Automate connector health: Verify all connections (Microsoft Graph, BigTime API, SharePoint, Outlook) show 'Connected' status. Re-authenticate if any show expired.

Monthly Tasks (1–2 hours MSP effort)

  • Review automation flow performance: Check for slow-running steps, optimize queries, verify execution counts are within plan limits.
  • Update software: Apply any Power Automate connector updates, BigTime platform updates, or Ramp integration changes.
  • Billing rate card sync: Coordinate with client to update billing rates if any changed (new hires, annual rate increases, new project rates).
  • Security review: Verify API key/secret expiration dates; rotate secrets proactively 30 days before expiry. Verify service account permissions haven't been inadvertently changed.
  • Generate monthly MSP service report: Summarize automation uptime, match rates, hours auto-captured, estimated time savings, and any incidents resolved.

Quarterly Optimization Reviews (2–4 hours MSP effort; billed separately)

  • Deep analysis of match rate trends: Identify persistent unmatched patterns and implement new matching rules.
  • ROI analysis: Calculate actual billable hours recovered vs. baseline (pre-automation). Present to client leadership.
  • New project/client onboarding audit: Verify all new clients and projects added in the quarter are properly configured in lookup tables.
  • User adoption analysis: Identify low-adoption users and recommend targeted training.
  • Platform updates review: Evaluate new features in BigTime, Power Automate, or Ramp that could enhance the solution.
  • Compliance audit check: Verify audit trails are complete, retention policies are enforced, and approval workflows are functioning correctly.

Annual Tasks

  • Azure AD app registration secret rotation: Client secrets expire after 24 months; rotate proactively.
  • Annual compliance review: Full review of FLSA/SOX/DCAA compliance posture; update documentation for any regulatory changes.
  • Vendor contract renewals: Review BigTime, Ramp, and M365 licensing; negotiate MSP partner discounts.
  • Disaster recovery test: Verify that if the automation stops, employees can still enter time manually. Test failover procedures.
  • Architecture review: Assess whether the solution should evolve (e.g., add AI-powered matching, migrate to a different PSA, add new data sources).

SLA Framework

Escalation Path

1
Level 1: MSP automation technician (daily monitoring, routine fixes)
2
Level 2: MSP senior engineer (API issues, complex flow debugging, platform outages)
3
Level 3: Vendor support (BigTime, Microsoft, Ramp support tickets for platform-level issues)
4
Client escalation: Operations Manager → MSP Account Manager for SLA concerns

Alternatives

PSOhub Self-Driving Time Tracking (All-in-One PSA)

Replace the custom Power Automate + BigTime architecture with PSOhub, which has native 'self-driving' time tracking that automatically generates time entries from Outlook and Google Calendar without requiring a separate automation engine. PSOhub is purpose-built for this exact use case and integrates natively with HubSpot and Salesforce CRM.

Zapier + Harvest (Google Workspace Stack)

For clients on Google Workspace (not Microsoft 365), replace Power Automate with Zapier as the automation engine and BigTime with Harvest as the time tracking platform. Zapier has excellent Google Calendar triggers and Harvest connectors. This is a simpler, lighter-weight stack suited for smaller firms.

n8n Self-Hosted (Data-Sensitive / Cost-Optimized)

Replace cloud-based Power Automate with self-hosted n8n on an on-premises Intel NUC or cloud VM. All automation logic runs on infrastructure the MSP controls, with no per-execution fees. Calendar data and time entries are processed locally before being pushed to the PSA platform.

Manual Configuration in Existing PSA (Minimal Automation)

Instead of building a full automation pipeline, configure the client's existing or new PSA platform (BigTime, Scoro, Accelo) to leverage its built-in calendar sync and suggested time entry features. Many modern PSAs now include basic calendar integration that populates draft time entries without external automation. Layer on lightweight Zapier automations only for specific gaps.

Accelo ServOps Platform (Email-Centric Firms)

For professional services firms where most billable work happens via email (legal, consulting, accounting), Accelo automatically captures time spent on client emails and maps it to projects. This provides a different input signal — email activity rather than just calendar events — for more comprehensive time capture.

Want early access to the full toolkit?