
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
$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
$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
$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
$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
$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
$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)
$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)
$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
$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)
$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
$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
$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.
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.
- 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)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.
# 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: YESFirstName, LastName, Email, Role, DefaultBillRate, CostRate, Department
John,Smith,jsmith@clientdomain.com,Senior Consultant,175.00,85.00,AdvisoryProjectCode, ProjectName, ClientName, BudgetHours, BudgetAmount, StartDate, EndDate
ACME-2025-01,ACME Q1 Advisory,Acme Corp,500,87500,2025-01-01,2025-03-31Time 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 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 AMHarvest API Base URL: https://api.harvestapp.io/v2/
Auth: OAuth2 — account ID + personal access token
Token management: id.getharvest.com/developersFor 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
STEP 2c-ii: Calculate duration
# 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
# 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/jsonSTEP 2c-iv: Create draft time entry
# 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 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.
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
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)
GET https://iq.bigtime.net/BigtimeData/api/v2/staff?email=[user_email]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
POST https://[resource].cognitiveservices.azure.com/formrecognizer/documentModels/prebuilt-receipt:analyzeRamp 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:
<!-- 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:
{
"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
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
@{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))}Power BI Dashboard (Optional but Recommended)
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.
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.
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
Initial Sync Test
Xero API Endpoint (Alternative Integration)
https://api.xero.com/api.xro/2.0/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
{
"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
{
"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
eventSubjectcontains 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:
contains(toLower(triggerBody()?['eventSubject']), toLower(items('Apply_to_each')?['Keyword']))If TRUE, set the following match variables:
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'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 usingsplit(items('Apply_to_each_attendee'), '@')[1] - Skip if domain equals employee's own domain
- Check if domain exists in
ClientDomainslist
If TRUE, set the following match variables:
matchFound = true
matchMethod = 'Domain'
projectCode = items('Domain_lookup')?['DefaultProjectCode']
confidence = 'Medium'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
eventCategoriescontains any value matching a project code pattern (regex:[A-Z]+-\d{4}-\d+) - If TRUE: Look up the category value in
ProjectKeywordslist - Set match with
confidence = 'High'(explicit tag is reliable)
Step 5: Calculate Duration
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: Setbillable = 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.
Option A: Ramp Webhook Integration (Recommended)
Ramp Webhook Setup
https://[your-logic-app-or-power-automate-url]transaction.created, transaction.updatedPower Automate Flow
Trigger: When an HTTP request is received Method: POST
{
"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"}}
}
}
}
}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"
}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
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]GET https://[resource-name].cognitiveservices.azure.com/formrecognizer/documentModels/prebuilt-receipt/analyzeResults/[resultId]?api-version=2023-07-31{
"MerchantName": "Marriott Downtown",
"Total": 289.50,
"TransactionDate": "2025-07-14",
"Items": [
{"Description": "Room - King Suite", "Amount": 249.00},
{"Description": "Tax", "Amount": 40.50}
]
}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
GET https://iq.bigtime.net/BigtimeData/api/v2/staff?IsActive=true
Headers: X-Auth-Token: [API_KEY]GET https://iq.bigtime.net/BigtimeData/api/v2/time?StaffSID=[sid]&StartDt=[yesterday]&EndDt=[yesterday]
Headers: X-Auth-Token: [API_KEY]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]"
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
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 * 100Step 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
SharePoint List: WeeklyComplianceLog
Columns: WeekEnding, StaffEmail, HoursLogged, TargetHours, CompletionPct, AutoMatchPct, OverdueDraftsConfiguration 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:
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 * 100Step 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)
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
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
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
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?