Reimbursements and Expenses
Expense capture, receipt upload, approval, rejection, resubmission, invoicing, and Xero bill submission.
Domain model
Reimbursements are implemented as Expense records.
Important fields:
| Field | Meaning |
|---|---|
date | Purchase or claim date. |
category, categoryMaster, projectCategory | Category label or linked category configuration. |
amount, currency | Claim amount. |
description | Purchase or reimbursement description. |
receiptUrl, attachments | Receipt evidence and uploaded attachments. |
status | draft, submitted, accepted, approved, or rejected. |
location | Optional metadata payload. |
rejectionReason, returnToRole | Rejection workflow information. |
xeroSubmittedAt, xeroSubmissionReference, xeroSubmissionError | Xero submission state. |
user, project | Claimant and project scope. |
Status lifecycle
draft
-> submitted
-> accepted
-> approved
-> invoice generation or Xero submission
-> rejected
-> returned to electrician, supervisor, or payroll manager depending on return roleThe same enum values as timesheets are used for the broad review states, but expenses have their own ExpenseStatus enum and controller paths.
Capture workflow
Electrician-facing paths and API endpoints let workers create and update expenses. A typical claim includes:
- client and project selection
- date
- expense category
- amount
- description
- receipt or attachment
- optional cost code/project category linkage
- submit for review
The product manifest calls this reimbursement flow. The code's entity name is Expense.
Review workflow
Supervisors and client/payroll users can review submitted expenses. The API v2 supervisor surface includes:
- list expenses
- approve expense
- reject expense
- resubmit expense
Portal controllers also expose expense review and bulk actions for client and payroll flows.
Invoice workflow
Approved expenses are eligible for PayrollInvoiceService invoice generation. The invoice service:
- finds approved expenses in client/project scope
- excludes expenses already linked to blocking invoice statuses
- creates
PayrollInvoiceItemrows withsourceType = expense - uses the approved expense amount as the invoice item amount
Blocking invoice statuses are draft, pending, generated, approved, submitted_to_xero, and paid. void does not block a source record from being invoiced again.
Xero workflow
Expenses can be submitted through Xero endpoints or services. XeroBillSubmissionService submits expenses as bills using Xero AP invoice behavior, which is more reliable with demo accounts than Xero expense claims.
Each submission stores the result back on the expense:
- success reference
- submitted timestamp
- error message when submission fails
Notifications
TimesheetExpenseNotificationService sends notifications for expense approval and rejection. It persists inbox notifications and delegates mobile push payload delivery to Expo push services.