What is this file?
No report loaded
Ask a chart question in the , then click "Open in Reports".
Saved Templates
General Ledger
Full-year transaction ledger for your accountant. Payroll (W-2) and Outside Labor (1099) are kept as separate accounts.
No transactions found for {{ glYearEffective }} Β· {{ glAccountFilter }}.
| Category / Sub-Category | Txns | Net Amount |
|---|---|---|
| {{ c.category }} | {{ c.count }} | {{ formatCurrency(c.total) }} |
| {{ s.sub }} | {{ s.count }} | {{ formatCurrency(s.total) }} |
Your Restaurants
Select a restaurant to view its books.
{{ r.name }}
{{ r.role }}{{ activeRestaurant?.name || 'Portioned' }}
{{ plDateRange.label }}
P&L Summary
View your profit & loss statement
Distributions
Track owner distributions and reimbursements
Chat with your accountant
Ask questions about your financials
Transactions
Import data, categorize, and manage your transactions
{{ uncategorizedCount }} need reviewP&L Summary
View your profit & loss statement
Prime Cost
Track food, beverage, and labor costs
Sales
Daily revenue, covers, daypart & payment mix
Charts
Visualize spending by category
Invoices
Upload invoices and track what's due
Distributions
Track owner distributions and reimbursements
Reconciliation
Compare balances with bank statements
Cash Flow
Track actual cash in and out
Vendors
Manage vendor contacts and payment details
{{ vendorsNeedingSetupCount }} need setupRules
Manage auto-categorization rules
Getting Started
- Click Import Data to upload your bank and POS CSV files
- Review and categorize your transactions
- View your P&L and Prime Cost reports
Inbox
{{ inboxPendingCount }} items need attention
All caught up β
{{ currentBatchStepConfig.name }}
{{ currentBatchStepConfig.description }}
No transfer matches detected, or all matches have been reviewed.
All Transactions Categorized
No uncategorized transactions to process.
Categorize by Vendor
{{ currentBatchTransactions.length }} uncategorized transactions across {{ aiClusters.length }} vendors{{ checkClusters.length ? ' (+ ' + checkClusters.reduce((s,g) => s + g.transactions.length, 0) + ' checks excluded)' : '' }}. Create rules for the ones you recognize β they'll auto-categorize on every future import.
All vendors handled.
Processing {{ batchAiState.totalTransactions }} transactions...
All suggestions reviewed.
Vendors you've categorized the same way before β high confidence
No transactions in this category.
{{ showAllBatchTransactions ? 'All' : 'Preview' }} ({{ showAllBatchTransactions ? filteredBatchTransactions.length : Math.min(filteredBatchTransactions.length, 10) }} of {{ filteredBatchTransactions.length }})
| Rule | Date | Details | Amount | Type | Category | Sub Cat | |
|---|---|---|---|---|---|---|---|
| {{ t.Date }} | {{ t.Details }} | {{ formatCurrency(t.Amount) }} | {{ t['Transaction Type'] || 'β' }} | {{ t.Category }} Pending | {{ t['Sub Cat'] || 'β' }} |
+ {{ filteredBatchTransactions.length - 10 }} more transactions
No transactions in this category.
{{ currentBatchTransactions.filter(t => !t.Category).length }} uncategorized of {{ currentBatchTransactions.length }} total
| Rule | Date | Details | Amount | Category | |
|---|---|---|---|---|---|
| {{ t.Date }} | {{ t.Details }} | {{ formatCurrency(t.Amount) }} | β |
+ {{ currentBatchTransactions.filter(t => !t.Category).length - 15 }} more uncategorized
Upload Bank Statements ({{ processingResults.filter(r => r.status === 'success' || r.status === 'warning').length }} files processed)
Drag & drop CSV/XLSX files or click to select. Supports AMEX, Chase, Bluevine, Toast, Stripe, ADP Payroll.
Drop files here...
Drag & drop CSV/XLSX files here, or click to select
Selected Files ({{ selectedFiles.length }})
Processing Results
β {{ nearDuplicates.length }} Near-Duplicate{{ nearDuplicates.length > 1 ? 's' : '' }} Found
These transactions have the same date and amount as existing transactions but different descriptions. They may be duplicates from different sources (e.g., CSV import vs QuickBooks).
+ {{ nearDuplicates.length - 5 }} more...
Review these in the transaction table below.
Transactions ({{ transactions.length }})
Step {{ currentBatchStep + 1 }} of {{ batchSteps.length }}: {{ currentBatchStepConfig.name }}
{{ currentBatchStepConfig.description }}
No transfer matches detected, or all matches have been reviewed.
All Transactions Categorized
No uncategorized transactions to process. Great job!
Categorize by Vendor
{{ currentBatchTransactions.length }} uncategorized transactions across {{ aiClusters.length }} vendors. Create rules for the ones you recognize.
All vendors handled.
Processing {{ batchAiState.totalTransactions }} transactions...
No {{ batchAiState.currentTier }} confidence suggestions
{{ group.vendor }}
{{ group.transactions.length }} transaction{{ group.transactions.length > 1 ? 's' : '' }} β {{ group.suggestion.category }} / {{ group.suggestion.subCategory }} {{ group.suggestion.reasoning }}No transactions in this category.
{{ showAllBatchTransactions ? 'All' : 'Preview' }} ({{ showAllBatchTransactions ? filteredBatchTransactions.length : Math.min(filteredBatchTransactions.length, 10) }} of {{ filteredBatchTransactions.length }})
| Rule | Date | Details | Amount | Type | Category | Sub Cat | |
|---|---|---|---|---|---|---|---|
| {{ t.Date }} | {{ t.Details }} | {{ formatCurrency(t.Amount) }} | {{ t['Transaction Type'] || 'β' }} | {{ t.Category }} Pending | {{ t['Sub Cat'] || 'β' }} |
+ {{ filteredBatchTransactions.length - 10 }} more transactions
No transactions in this category.
{{ currentBatchTransactions.filter(t => !t.Category).length }} uncategorized of {{ currentBatchTransactions.length }} total
| Rule | Date | Details | Amount | Category | |
|---|---|---|---|---|---|
| {{ t.Date }} | {{ t.Details }} | {{ formatCurrency(t.Amount) }} | β |
+ {{ currentBatchTransactions.filter(t => !t.Category).length - 15 }} more uncategorized
Batch Review Complete!
All {{ transactions.length }} transactions have been processed.
Review Complete!
All {{ transactions.length }} transactions have been processed.
Category Breakdown
No transactions to review.
Check to mark all selected transactions as needing review
AI will analyze relationships and suggest categories for all selected transactions
| Rule | Date {{ sortDirection === 'asc' ? 'β²' : 'βΌ' }} | Details {{ sortDirection === 'asc' ? 'β²' : 'βΌ' }} | Amount {{ sortDirection === 'asc' ? 'β²' : 'βΌ' }} | Bank | Card | Category | Sub Cat | Company | Flag | ||
|---|---|---|---|---|---|---|---|---|---|---|---|
| {{ t.Date }} β β | {{ t.Details }} | {{ formatCurrency(t.Amount) }} | {{ t.Bank }} | {{ t.Card ? '...' + t.Card : 'β' }} | {{ t.Category || 'β' }} Γ{{ t._ruleMatches.length }} QB: {{ t._qboCategory }} | {{ t['Sub Cat'] || 'β' }} | {{ t['Company / Employee'] || 'β' }} | β οΈ Review Transfer Dist: {{ t.Owner }} Reimb: {{ t.Owner }} Principal β | π |
Fintech Vendor Matches
These Fintech invoices may match existing vendors. Confirm to link them and optionally update vendor info.
Vendor Management
| Vendor | Contact Info | Payment Method | Termsstated / measured | YTD Spend | Last Transaction | Status | Actions |
|---|---|---|---|---|---|---|---|
|
{{ vendor.name }}
Needs Setup
{{ vendor.type || 'β' }}
|
{{ vendor.primaryContact?.name || 'β' }}
{{ vendor.primaryContact?.phone || '' }}
|
{{ vendor.paymentInfo.method }} {{ vendor.paymentInfo.fundingAccount }} AUTO-PAY β |
{{ vendor.paymentInfo.terms }}
β
{{ vendorTermsByVendorId[vendor.id].label }}
{{ vendorTermsByVendorId[vendor.id].confidence.label }}
β stated terms
|
{{ formatCurrency(getVendorSpend(vendor.name, 'ytd')) }}
{{ getVendorTransactionCount(vendor.name) }} transactions
|
{{ formatDate(getVendorLastTransactionDate(vendor.name)) }}
{{ formatRelativeDate(getVendorLastTransactionDate(vendor.name)) }}
|
Active
Inactive
Ignored
|
|
Categorization Rules ({{ rules.length }})
Found {{ duplicateRuleCount }} group{{ duplicateRuleCount > 1 ? 's' : '' }} of similar rules that might be consolidatable.
Loading your dataβ¦
No transactions loaded. Upload and process CSV files first to generate the P&L report.
Profit & Loss Summary
Leitao Restaurant
Where every dollar of revenue goes
Each bar is scaled to 100% of revenue, so you compare share β not size. Watch the green profit slice change.
No data for the same period last year, so there's nothing to compare against yet.
| Line item | {{ plYoy.priLabel }} $ | % | {{ plYoy.bars[plYoy.bars.length-1].label }} $ | % | Ξ pts |
|---|---|---|---|---|---|
| {{ row.label }} | {{ row.priVal }} | {{ row.priPct }}% | {{ row.curVal }} | {{ row.curPct }}% | {{ row.deltaStr }} |
Profit & Loss Statement
| Category | Cash | Accrual | Ξ (AccβCash) |
|---|---|---|---|
| {{ row.label }} | |||
| {{ row.label }} | {{ row.cash == null ? 'β' : formatCurrency(row.cash) }} | {{ row.accrual == null ? 'β' : formatCurrency(row.accrual) }} | {{ row.delta == null ? 'β' : (row.delta > 0 ? '+' : '') + formatCurrency(row.delta) }} |
| {{ row.label }} | {{ formatCurrency(row.cash) }} | {{ formatCurrency(row.accrual) }} | {{ row.delta > 0 ? '+' : '' }}{{ formatCurrency(row.delta) }} |
| {{ row.label }} | {{ formatCurrency(row.cash) }} | {{ formatCurrency(row.accrual) }} | {{ row.delta > 0 ? '+' : '' }}{{ formatCurrency(row.delta) }} |
Ξ = Accrual β Cash. Both bases now recognize a card charge when it is swiped β a cash-basis taxpayer deducts a card charge when charged, so payments to the card are debt repayment, not expense. Revenue differs because accrual uses POS sales, cash uses bank deposits. Highlighted rows exist in only one basis. Exports still use the page basis ({{ accountingBasis === 'cash' ? 'Cash' : 'Accrual' }}).
| Category | Amount | % of Revenue |
|---|---|---|
| REVENUE | ||
| {{ source }} | {{ formatCurrency(amount) }} | {{ pctOfRevenue(amount, plReport.totalRevenue) }} |
|
{{ txn.Date }}
{{ txn.Details }}
{{ formatCurrency(txn.Amount) }}
|
||
| Other Income (Interest, Cash Back) | {{ formatCurrency(plReport.otherIncome) }} | {{ pctOfRevenue(plReport.otherIncome, plReport.totalRevenue) }} |
| Total Revenue | {{ formatCurrency(plReport.totalRevenue) }} | 100.0% |
| COST OF GOODS SOLD | ||
| {{ subCat }} | {{ formatCurrency(-amount) }} | {{ pctOfRevenue(amount, plReport.totalRevenue) }} |
|
{{ txn.Date }}
{{ txn.Details }}
{{ formatCurrency(txn.Amount) }}
|
||
| (No COGS transactions) | $0.00 | 0.0% |
| Total COGS | {{ formatCurrency(-plReport.totalCOGS) }} | {{ plReport.cogsPercent.toFixed(1) }}% |
| GROSS PROFIT | {{ formatCurrency(plReport.grossProfit) }} | {{ plReport.grossProfitPercent.toFixed(1) }}% |
| LABOR | ||
| {{ subCat }} | {{ formatCurrency(-amount) }} | {{ pctOfRevenue(amount, plReport.totalRevenue) }} |
|
{{ txn.Date }}
{{ txn.Details }}
{{ formatCurrency(txn.Amount) }}
|
||
| (No labor transactions) | $0.00 | 0.0% |
| Total Labor | {{ formatCurrency(-plReport.totalLabor) }} | {{ plReport.laborPercent.toFixed(1) }}% |
| PRIME COST (COGS + Labor) | {{ formatCurrency(-plReport.primeCost) }} | {{ plReport.primeCostPercent.toFixed(1) }}% |
| OPERATING EXPENSES | ||
| {{ category }} | {{ formatCurrency(-catData.total) }} | {{ pctOfRevenue(catData.total, plReport.totalRevenue) }} |
|
{{ txn.Date }}
{{ txn.Details }}
{{ formatCurrency(txn.Amount) }}
|
||
| (No operating expense transactions) | $0.00 | 0.0% |
| Total Operating Expenses | {{ formatCurrency(-plReport.totalOpex) }} | {{ plReport.opexPercent.toFixed(1) }}% |
| OPERATING PROFIT | {{ formatCurrency(plReport.operatingProfit) }} | {{ plReport.operatingProfitPercent.toFixed(1) }}% |
| TAXES | ||
| {{ subCat }} | ({{ formatCurrency(amount) }}) | {{ pctOfRevenue(amount, plReport.totalRevenue) }} |
|
{{ txn.Date }}
{{ txn.Details }}
{{ formatCurrency(txn.Amount) }}
|
||
| Total Taxes | ({{ formatCurrency(plReport.totalTaxes) }}) | {{ plReport.taxesPercent.toFixed(1) }}% |
| NET INCOME | {{ formatCurrency(plReport.netIncome) }} | {{ plReport.netIncomePercent.toFixed(1) }}% |
| OWNER PUT BACK β memo only Personal expenses that ran through the business accounts (e.g. on a business credit card). Shown for visibility only β they are NOT added back into Distributable Net, because personal spend is already excluded from COGS, Labor and Opex. Each owner repays their own share through the "Less: Personal expenses" deduction on the distribution report. | ||
| Personal Expenses (Owner Owes Business) | {{ formatCurrency(plReport.nonOperating.ownerReimbursables) }} | {{ (plReport.nonOperating.ownerReimbursables / plReport.totalRevenue * 100).toFixed(1) }}% |
| {{ ownerDisplayName(owner) }} | + {{ formatCurrency(amount) }} | {{ (amount / plReport.nonOperating.ownerReimbursables * 100).toFixed(1) }}% |
|
{{ txn.Date }}
{{ txn.Details }}
{{ formatCurrency(txn.Amount) }}
|
||
| DISTRIBUTABLE NET Net Income plus the owner put back. This is the real amount available to distribute among owners after accounting for personal expenses that flowed through the business. | {{ formatCurrency(plReport.distributableNet) }} | {{ plReport.distributableNetPercent.toFixed(1) }}% |
| NON-P&L CASH MOVEMENTS These transactions moved real cash but are excluded from the P&L because they are balance sheet activity β not income or expenses. Transfers between accounts (like CC payments or savings moves), owner distributions, and loan principal repayments don't change your profitability; they only move money between accounts or represent equity changes. | {{ showNonPlSection ? 'hide' : 'show' }} | |
| Transfers (CC payments, savings, inter-account) | - | - |
|
{{ txn.Date }}
{{ txn.Details }}
{{ formatCurrency(txn.Amount) }}
|
||
| Guaranteed Payments / Distributions | - | - |
|
{{ txn.Date }}
{{ txn.Details }}
{{ formatCurrency(txn.Amount) }}
|
||
| Loan Principal Payments | - | - |
|
{{ txn.Date }}
{{ txn.Details }}
{{ formatCurrency(txn.Amount) }}
|
||
Based on {{ plReport.transactionCount }} transactions from {{ plDateRange.startDate }} to {{ plDateRange.endDate }}
COG vs Revenue by Category
No POS data synced for {{ plMonth }}. Data syncs nightly β check back tomorrow, or verify your Toast connection in Settings.
| Category | Revenue (POS) | COG Spend | Cost % |
|---|---|---|---|
| {{ row.name }} | {{ row.revenue != null ? formatCurrency(row.revenue) : 'β' }} | {{ formatCurrency(row.cost) }} | {{ row.pct }}% β |
No transactions loaded. Upload and process CSV files first.
Prime Cost Dashboard
Leitao Restaurant
Prime Cost represents your two largest controllable expenses: Cost of Goods Sold (COGS) and Labor. This dashboard breaks down your revenue, food and beverage costs, labor expenses, and calculates your Prime Cost percentage. Industry best practice is to keep Prime Cost under 60% of revenue; 60β65% is a watch zone, and above 65% signals trouble for profitability. Use the expandable sales breakdown below to analyze performance by menu category and identify opportunities for margin improvement.
Total Revenue
Cost of Goods Sold
Labor Cost
Prime Cost
Cost Trends
What each ingredient group cost per month, on the {{ accountingBasis === 'accrual' ? 'accrual' : 'cash' }} basis. Spans its own window β the date selector above doesn't apply.
No COGS history yet. Once a few months of categorized purchases are imported, their trends show up here.
| Category | First {{ cogsTrendSummary[0].spanMonths }} mo avg | Last {{ cogsTrendSummary[0].spanMonths }} mo avg | Change |
|---|---|---|---|
| {{ row.label }} | {{ row.first == null ? 'β' : (cogsTrendMode === 'percent' ? row.first.toFixed(1) + '%' : formatCurrency(row.first)) }} | {{ row.last == null ? 'β' : (cogsTrendMode === 'percent' ? row.last.toFixed(1) + '%' : formatCurrency(row.last)) }} | β no change {{ row.delta > 0 ? 'β²' : 'βΌ' }} {{ cogsTrendMode === 'percent' ? Math.abs(row.delta).toFixed(1) + ' pts' : formatCurrency(Math.abs(row.delta)) }} ({{ row.deltaPct > 0 ? '+' : 'β' }}{{ Math.abs(row.deltaPct).toFixed(0) }}%) |
Key Performance Indicators
Toast Sales by Category
No Sales Category data available. Import Toast Category Summary to see detailed breakdowns.
Sales Dashboard
Toast POS Β· {{ salesRangeLabel }}
Sales Mix Trend
What each category sold per month, from Toast, over {{ salesRangeLabel }}. Monthly by design β before Mar 2026 Toast only gave us category totals per month, so a daily line there would be invented.
Loading sales historyβ¦
Couldn't load sales history: {{ salesError }}
A trend needs more than one month β pick a wider range above.
No POS sales history yet. Once Toast data syncs, category trends show up here.
| Category | First {{ salesMixSummary[0].spanMonths }} mo avg | Last {{ salesMixSummary[0].spanMonths }} mo avg | Change |
|---|---|---|---|
| {{ row.label }} | {{ row.first == null ? 'β' : (salesMixMode === 'percent' ? row.first.toFixed(1) + '%' : formatCurrency(row.first)) }} | {{ row.last == null ? 'β' : (salesMixMode === 'percent' ? row.last.toFixed(1) + '%' : formatCurrency(row.last)) }} | β no change {{ row.delta > 0 ? 'β²' : 'βΌ' }} {{ salesMixMode === 'percent' ? Math.abs(row.delta).toFixed(1) + ' pts' : formatCurrency(Math.abs(row.delta)) }} ({{ row.deltaPct > 0 ? '+' : 'β' }}{{ Math.abs(row.deltaPct).toFixed(0) }}%) |
Loading POS dataβ¦
No POS connection configured.
No POS data for {{ salesRangeLabel }}.
Data syncs nightly from Toast. You can also import historical data in Settings.
{{ posReport.multiMonth ? 'Revenue by Month' : 'Daily Revenue' }}
By Daypart
No daypart data available.
| Period | Revenue | Covers | Avg Check | % |
|---|---|---|---|---|
| {{ row.period }} | {{ formatCurrency(row.revenue) }} | {{ row.covers }} | {{ formatCurrency(row.avgCheck) }} | {{ row.pct.toFixed(1) }}% |
Sales Mix
No category data available.
Payment Types
No payment data available.
Cost of Goods vs Sales
Compares POS revenue by category against categorized COGS purchases. Requires vendors tagged with a COG type in Vendors settings.
| Category | POS Revenue | COGS Spend | Food Cost % | |
|---|---|---|---|---|
| {{ row.name }} | {{ row.revenue != null ? formatCurrency(row.revenue) : 'β' }} | {{ formatCurrency(row.cost) }} | {{ row.pct.toFixed(1) }}% | β |
Cost of Goods vs Sales
Tag vendors with a COG type (Food / Beverage / NA Bev) in to see food cost %.
Traffic Analysis
Hourly breakdown Β· outlier checks Β· weekday comparison
Loadingβ¦
No POS connection configured.
No data for {{ trafficDate || 'selected date' }}. Pick a day with POS data.
Revenue by Hour
Same Day β Prior Weeks
| Date | Revenue | Covers | Avg Check |
|---|---|---|---|
| {{ row.date }} | {{ formatCurrency(row.revenue) }} | {{ row.covers || 'β' }} | {{ row.avgCheck > 0 ? formatCurrency(row.avgCheck) : 'β' }} |
| No prior data available yet | |||
Large Checks avg {{ formatCurrency(trafficMeanAmount) }}
No check-level data available.
No unusually large checks β normal distribution.
| Table | Server | Amount | Covers |
|---|---|---|---|
| {{ o.table || 'β' }} | {{ o.server || 'β' }} | {{ formatCurrency(o.amount) }} | {{ o.covers || 'β' }} |
No transactions loaded. Upload and process CSV files first.
Category Breakdown Charts
Leitao Restaurant
Revenue Mix
Toast Sales Mix
Import Toast Category Summary to see sales mix.
Toast Sales by Category (Detail)
No Sales Category data available.
Key Cost Ratios
No payroll data imported yet
Download your Payroll Summary report from ADP and drag it into the import zone on the Transactions tab.
No labor costs in {{ laborSelectedYear }}
This report reads the Company / Employee field on Payroll Expense and Outside Labor transactions.
Labor by Person
π PrivatePay over time
One point per payment, so a steady wage draws a level line and an extra check shows as a spike. Pay rate, not monthly cash β the table below is the cash view and ties to the P&L. Fat dots are payments well above that person's usual. Tick anyone in the table below to add their line ({{ laborChartPeople.length }} of {{ laborChartMaxSeries }} slots used). Lines break across {{ laborUnknownMonths.size }} months where no payment carries a name β a gap means unknown, not zero.
No transactions loaded. Upload and process CSV files first.
Owner Distributions
{{ plDateRange.label }}
Owner Equity Reconciliation Β· {{ ownerEquityRollforward.year }} YTD
Through {{ ownerEquityRollforward.throughMonth }} Β· cash basis, after 10% reserveCumulative distributable pool: {{ formatCurrency(ownerEquityRollforward.totalAvailable) }}. Should-be-paid = each owner's share; net of personal charges owed; balance vs. actual payouts.
| Owner | Share | Entitled (gross) | Owes business | Entitled (net) | Actually paid | Balance |
|---|---|---|---|---|---|---|
| {{ row.owner }} | {{ row.pct }}% | {{ formatCurrency(row.entitledGross) }} | {{ row.owed > 0 ? '-' + formatCurrency(row.owed) : 'β' }} | {{ formatCurrency(row.entitledNet) }} | {{ formatCurrency(row.paid) }} | {{ row.balance > 0.5 ? '+' + formatCurrency(row.balance) : (row.balance < -0.5 ? '-' + formatCurrency(Math.abs(row.balance)) : formatCurrency(0)) }} |
| Total | 100% | {{ formatCurrency(ownerEquityRollforward.totalAvailable) }} | {{ ownerEquityRollforward.totalOwed > 0 ? '-' + formatCurrency(ownerEquityRollforward.totalOwed) : 'β' }} | {{ formatCurrency(ownerEquityRollforward.totalAvailable - ownerEquityRollforward.totalOwed) }} | {{ formatCurrency(ownerEquityRollforward.totalPaid) }} |
{{ outstandingTimingAdjustments.some(a => a.overdue) ? 'Timing adjustment overdue' : 'Outstanding timing adjustments' }}
{{ formatCurrency(outstandingTimingTotal) }} still to come backCash moved between months. Each one comes back out of its month automatically β there is nothing to remember β but none of it is settled until that month is closed.
| Amount | Added to | Comes back out of | Reason |
|---|---|---|---|
| {{ formatCurrency(a.amount) }} | {{ formatMonthKey(a.appliesMonth) }} | {{ formatMonthKey(a.reversesMonth) }} Β· still open | {{ a.reason || 'β' }} |
Distributable Net (Cash Basis)
Distributable Profit
Timing Adjustments
Move cash between two months' distribution pools. Both legs are booked at once, so the claw-back cannot be forgotten. This never touches the P&L.
Calculated Distributions
{{ showPersonalExpensesDetail ? 'βΌ' : 'βΆ' }} Personal Expenses Detail ({{ distributionsReport.reimbursableTransactions.length }} transactions)
These are personal expenses charged to business accounts that owners must pay back to the business.
| Date | Details | Category | Amount |
|---|---|---|---|
| {{ txn.date }} | {{ txn.details }} | {{ txn.category }} | {{ formatCurrency(txn.amount) }} |
Actual Disbursements
Closed {{ formatDate(lockedDistribution.locked_at?.slice(0,10)) }} by {{ lockedDistribution.locked_by_name }}. These figures are frozen β they are what the checks were written for and don't move when the books are reworked.
This month is still open, so everything above is recomputed live and will change if transactions are recategorised. Close it to freeze what each owner is actually paid.
Couldn't load the distribution ledger: {{ distributionLedgerError }}
| Owner | Declared | Paid | Variance | Books say now |
|---|---|---|---|---|
| {{ ownerDisplayName(row.owner) }} | {{ formatCurrency(row.declared) }} | {{ formatCurrency(row.paid) }} | β matches {{ row.variance > 0 ? '+' : 'β' }}{{ formatCurrency(Math.abs(row.variance)) }} | {{ formatCurrency((distributionDrift.owners.find(o => o.owner === row.owner) || {}).now || 0) }} |
| Total | {{ formatCurrency(distributionDeclaredVsPaid.totalDeclared) }} | {{ formatCurrency(distributionDeclaredVsPaid.totalPaid) }} | {{ formatCurrency(distributionDeclaredVsPaid.totalVariance) }} |
Provisional. "Declared" is the live calculation, not a frozen figure β it will move until the month is closed. Payments counted are transactions flagged owner-distribution dated {{ distributionDeclaredVsPaid.windowStart }} to {{ distributionDeclaredVsPaid.windowEnd }} ({{ distributionPaidWindowDays }} days past month-end, since the checks for a month are usually written the following one).
{{ distributionDeclaredVsPaid.transactions.length }} distribution payment(s) in this window
| Date | Owner | Details | Amount |
|---|---|---|---|
| {{ formatDate(t.date) }} | {{ ownerDisplayName(t.owner) }} | {{ t.details }} | {{ formatCurrency(t.amount) }} |
{{ lockedDistribution.superseded.length }} superseded version(s)
Pick a single calendar month to close it. A custom date range isn't a period anyone writes checks against.
No transactions loaded. Upload and process CSV files first.
Bank Reconciliation
{{ reconciliationReport.monthLabel }}
POS Revenue Check
Compare your POS report totals against what Portioned recorded as Sales
Reconciliation History
No reconciliation history yet. Reconcile your accounts above to see history here.
| Month | Source / Account | Variance | Notes | Status | Reconciled | ||
|---|---|---|---|---|---|---|---|
|
{{ group.monthLabel }}
{{ group.dateRange }}
|
{{ group.source }} | ||||||
| ββ {{ accountDisplayName(recon.source + '|' + recon.account, recon.source, recon.account) }} | {{ formatCurrency(recon.variance) }} | {{ recon.status }} | β | {{ formatReconciledDate(recon.reconciledAt) }} | |||
Cash Reconciliation
Toast cash sales vs counter deposits · year to date through {{ plDateRange.label }}
Cash Sales Reconciliation
POS cash vs bank deposits · {{ cashReconciliation.monthsCovered }} of {{ cashReconciliation.monthsTotal }} months with POS data| Month | POS cash collected | Deposited to bank | Variance | Running gap |
|---|---|---|---|---|
| {{ row.month }} | {{ formatCurrency(row.collected) }} | {{ formatCurrency(row.deposited) }} | {{ formatCurrency(row.variance) }} | {{ formatCurrency(cashReconciliation.rows.slice(0, i + 1).reduce((s, r) => s + r.variance, 0)) }} |
| YTD | {{ formatCurrency(cashReconciliation.totalCollected) }} | {{ formatCurrency(cashReconciliation.totalDeposited) }} | {{ formatCurrency(cashReconciliation.cumulative) }} |
POS cash includes sales tax and cash tips, so it will not tie to deposits to the dollar. Single-month swings are deposit timing; the running gap is the number to watch.
Tasks {{ openTaskCount }}
Loading tasksβ¦
{{ tasksFilter === 'mine' ? 'No tasks assigned to you.' : 'All clear β no open tasks.' }}
π Transaction Types Guide
Understanding how different transaction types affect your Profit & Loss (P&L) and owner distributions.
π Transfer
- Transfer $12,000 from checking to savings
- Move money from Bluevine to Chase checking
- Transfer to a reserve/holding account
- Category: "Transfer" (or leave blank)
- Sub Category: "From Savings" or "To Savings" (optional, helps track direction)
- Transfer Destination: Name of the other account (e.g., "Leitao Savings 4753")
NO IMPACT Excluded from revenue and expenses. Not counted as profit or loss.
NO IMPACT Money stays in the business. Still available for distribution (just in a different account).
π° Owner Distribution
- Monthly profit distribution to partners
- Year-end bonus distribution
- Draw against profits
- Category: Leave blank (or "Owner Distribution")
- Sub Category: Leave blank (or owner name)
- Owner Name: Required (Nuno, Daniel, Naum)
NO IMPACT Excluded from expenses. Distributions come FROM profit, not reduce profit.
TRACKED Recorded in Distributions report. Reduces owner's remaining distribution balance.
π§Ύ Owner Reimbursable
- Daniel bought supplies with personal credit card
- Nuno paid vendor invoice from personal account
- Owner covered payroll shortfall personally
- Category: The actual expense category (e.g., "COG", "Utilities", "Repairs")
- Sub Category: Appropriate subcategory (e.g., "Wine", "Electric")
- Owner Name: Required (who paid it)
REDUCES PROFIT Counted as expense in P&L. It's a real business expense.
INCREASES OWNER'S SHARE Added back to owner's distribution (business owes them). Deducted from other owners' shares.
π¦ Loan Principal Payment
- $2,000 loan payment: $300 interest + $1,700 principal
- The $1,700 principal portion should be flagged
- The $300 interest is a regular expense (Category: "Loan", Sub: "Interest")
- Category: "Loan" or "Loan Payment"
- Sub Category: "Principal" or lender name
- Note: Interest portion is separate (regular expense)
NO IMPACT Excluded from expenses. Paying debt doesn't reduce profit (interest does, but not principal).
NO IMPACT Doesn't affect distributions. It's a balance sheet item (reduces liability and cash).
π Quick Reference
| Flag Type | Affects P&L? | Affects Distributions? | Category Needed? |
|---|---|---|---|
| Transfer | No | No | Optional |
| Owner Distribution | No | Yes - Tracked | Optional |
| Owner Reimbursable | Yes - Expense | Yes - Owner + | Required |
| Principal Payment | No | No | Optional |
Cash Flow Statement
{{ businessName }}
π΅ What is a Cash Flow Statement?
The Cash Flow Statement tracks when money actually moves in and out of your bank accounts. It answers: "What happened to my cash balance this month?"
Key difference from P&L: Your P&L (accrual basis) records revenue when earned and expenses when incurred. Cash Flow records when deposits hit your bank and when payments clear.
Why it matters: You can be profitable on your P&L but run out of cash if timing doesn't align. This statement helps you manage working capital and understand why your bank balance changed.
Cash Flow from Operating Activities
| Cash receipts from operations | {{ formatCurrency(cashFlowReport.operatingReceipts) }} |
| Cash paid for goods (COGS) | {{ formatCurrency(-cashFlowReport.cashPaidCOGS) }} |
| Cash paid for labor | {{ formatCurrency(-cashFlowReport.cashPaidLabor) }} |
| Cash paid for operating expenses | {{ formatCurrency(-cashFlowReport.cashPaidOpex) }} |
| Cash paid for fees | {{ formatCurrency(-cashFlowReport.cashPaidFees) }} |
| Net cash from operating activities | {{ formatCurrency(cashFlowReport.netCashFromOperations) }} |
Cash Flow from Investing Activities
| Cash paid for equipment/furniture | {{ formatCurrency(-cashFlowReport.cashPaidForAssets) }} |
| Net cash from investing activities | {{ formatCurrency(cashFlowReport.netCashFromInvesting) }} |
Cash Flow from Financing Activities
| Loan proceeds | {{ formatCurrency(cashFlowReport.loanProceeds) }} |
| Loan principal payments | {{ formatCurrency(-cashFlowReport.loanPayments) }} |
| Owner distributions | {{ formatCurrency(-cashFlowReport.ownerDistributions) }} |
| Net cash from financing activities | {{ formatCurrency(cashFlowReport.netCashFromFinancing) }} |
| Net increase (decrease) in cash | {{ formatCurrency(cashFlowReport.netChangeInCash) }} |
| Cash at beginning of period | {{ formatCurrency(cashFlowReport.beginningBalance) }} |
| Cash at end of period | {{ formatCurrency(cashFlowReport.endingBalance) }} |
π Accrual vs Cash Reconciliation
Understand the difference between your P&L (accrual) and Cash Flow (cash basis)
| Item | Amount | % Diff |
|---|---|---|
| Revenue | ||
| Accrual Revenue (P&L - when earned) | {{ formatCurrency(plReport.totalRevenue) }} | 100% |
| Cash Receipts (Cash Flow - when received) | {{ formatCurrency(cashFlowReport.operatingReceipts) }} | {{ formatPercent((cashFlowReport.operatingReceipts / plReport.totalRevenue - 1) * 100) }}% |
| Timing Difference | {{ formatCurrency(cashFlowReport.operatingReceipts - plReport.totalRevenue) }} | See explanation below |
| Expenses | ||
| Accrual Expenses (P&L - when incurred) | {{ formatCurrency(-(plReport.totalCOGS + plReport.totalLabor + plReport.totalOpex)) }} | 100% |
| Cash Payments (Cash Flow - when paid) | {{ formatCurrency(-(cashFlowReport.cashPaidCOGS + cashFlowReport.cashPaidLabor + cashFlowReport.cashPaidOpex + cashFlowReport.cashPaidFees)) }} | {{ formatPercent(((cashFlowReport.cashPaidCOGS + cashFlowReport.cashPaidLabor + cashFlowReport.cashPaidOpex + cashFlowReport.cashPaidFees) / (plReport.totalCOGS + plReport.totalLabor + plReport.totalOpex) - 1) * 100) }}% |
| Timing Difference | {{ formatCurrency(-((cashFlowReport.cashPaidCOGS + cashFlowReport.cashPaidLabor + cashFlowReport.cashPaidOpex + cashFlowReport.cashPaidFees) - (plReport.totalCOGS + plReport.totalLabor + plReport.totalOpex))) }} | See explanation below |
| Bottom Line | ||
| Net Profit (P&L - accrual basis) | {{ formatCurrency(plReport.netProfit) }} | - |
| Net Cash from Operations (Cash Flow) | {{ formatCurrency(cashFlowReport.netCashFromOperations) }} | - |
π Why Are They Different?
Accrual P&L records revenue when earned (Toast/Stripe sales) and expenses when incurred (invoices received).
Cash Flow records when money actually moves - deposits hit your bank 1-3 days after sales, and credit card payments clear days after purchases.
π‘ What This Means:
Higher cash receipts than P&L revenue? You're collecting deposits from previous period's sales.
Lower cash receipts than P&L revenue? End-of-period sales haven't deposited yet - they'll show up next month's cash flow.
Higher cash payments than P&L expenses? You're paying off previous period's bills (accounts payable).
Lower cash payments than P&L expenses? You have unpaid bills that will be paid next period.
{{ priceHistory.selectedName }}
| Date | Vendor | Qty | Unit | Unit Price | Total | |
|---|---|---|---|---|---|---|
| {{ row.invoice_date }} | {{ row.vendor_name || 'β' }} | {{ row.qty != null ? row.qty : 'β' }} | {{ [row.size, row.unit_type].filter(Boolean).join(' ') }} β | ${{ row.unit_price != null ? Number(row.unit_price).toFixed(2) : 'β' }} {{ priceChangePct(row.unit_price, priceHistory.history[i+1].unit_price) > 0 ? '+' : '' }}{{ priceChangePct(row.unit_price, priceHistory.history[i+1].unit_price).toFixed(1) }}% | ${{ row.total != null ? Number(row.total).toFixed(2) : 'β' }} |
Upload your monthly CSV from fintech.com to import detailed beverage invoice line items.
The system found multiple possible invoice groupings for each transaction below. Confirm the right one or skip if unsure.
Invoice Inbox
Upload an invoice PDF or image to extract and track it.
- {{ String(f).replace(/_/g, ' ') }}
| Product | Qty | Unit | Price | Total |
|---|---|---|---|---|
| {{ li.description || 'β' }} | {{ li.qty ?? 'β' }} | {{ li.unit_of_measure || 'β' }} | ${{ li.unit_price != null ? Number(li.unit_price).toFixed(2) : 'β' }} | ${{ li.total != null ? Number(li.total).toFixed(2) : 'β' }} -${{ Math.abs(Number(li.total_discount)).toFixed(2) }} |
| Category | Opening | Received | Sold (est.) | Closing Count | Variance | Pour Cost |
|---|---|---|---|---|---|---|
| {{ invCategoryEmoji(cat) }} {{ cat }} | {{ invCategoryRows[cat]?.opening.value > 0 ? formatCurrency(invCategoryRows[cat].opening.value) : 'β' }} | {{ invCategoryRows[cat]?.received.value > 0 ? formatCurrency(invCategoryRows[cat].received.value) : 'β' }} | ~{{ Math.round(invCategoryRows[cat].soldQty) }} btl β | {{ invCategoryRows[cat]?.closing.value > 0 ? formatCurrency(invCategoryRows[cat].closing.value) : 'β' }} | {{ formatCurrency(Math.abs(invCategoryRows[cat].varianceVal)) }} {{ invCategoryRows[cat].varianceVal > 50 ? 'loss' : invCategoryRows[cat].varianceVal < -50 ? 'gain' : '~ok' }} n/a | {{ invCategoryRows[cat].pourCost.toFixed(1) }}% β |
| Total Beverage | {{ invTotals.opening.value > 0 ? formatCurrency(invTotals.opening.value) : 'β' }} | {{ invTotals.received.value > 0 ? formatCurrency(invTotals.received.value) : 'β' }} | β | {{ invTotals.closing.value > 0 ? formatCurrency(invTotals.closing.value) : 'β' }} | {{ formatCurrency(Math.abs(invTotals.variance)) }} n/a | {{ invTotals.pourCost.toFixed(1) }}% β |
| Product | Category | Opening | Received | Sold (est.) | Closing | Variance $ | Variance % |
|---|---|---|---|---|---|---|---|
| {{ p.description }} | {{ p.beverage_type || 'Other' }} | {{ invOpening[p.product_key] ? formatCurrency(invOpening[p.product_key].value) : 'β' }} | {{ invReceivedByProduct[p.product_key] ? formatCurrency(invReceivedByProduct[p.product_key].value) : 'β' }} | β | {{ p.latest_unit_cost ? formatCurrency(parseFloat(invCounts[p.product_key]) * p.latest_unit_cost) : 'β' }} | {{ formatCurrency(Math.abs(((invOpening[p.product_key]?.value||0) + (invReceivedByProduct[p.product_key]?.value||0)) - ((parseFloat(invCounts[p.product_key])||0)*(p.latest_unit_cost||0)))) }} n/a | β |
| Total Counted Items | β | β | β | {{ formatCurrency(invCountedValue) }} | n/a | β | |
{{ (pourStandards.wine.bottle_ml / 29.5735).toFixed(1) }} β {{ pourStandards.wine.waste_oz }} oz waste = {{ ((pourStandards.wine.bottle_ml / 29.5735) - pourStandards.wine.waste_oz).toFixed(1) }} oz usable
Γ· {{ pourStandards.wine.pour_oz }} oz/glass = {{ (((pourStandards.wine.bottle_ml / 29.5735) - pourStandards.wine.waste_oz) / pourStandards.wine.pour_oz).toFixed(2) }} glasses
Γ ${{ pourStandards.wine.avg_price_per_glass }} = ${{ wineRevPerBottle.toFixed(2) }} revenue / bottle
Γ· {{ pourStandards.spirits.cocktail_oz }} oz = {{ (pourStandards.spirits.bottle_ml / 29.5735 / pourStandards.spirits.cocktail_oz).toFixed(1) }} pours / bottle
{{ pourStandards.spirits.cocktail_pct }}% Γ ${{ pourStandards.spirits.cocktail_price }} + {{ 100 - pourStandards.spirits.cocktail_pct }}% Γ ${{ pourStandards.spirits.shot_price }} = ${{ ((pourStandards.spirits.cocktail_pct / 100) * pourStandards.spirits.cocktail_price + ((100 - pourStandards.spirits.cocktail_pct) / 100) * pourStandards.spirits.shot_price).toFixed(2) }} avg
= ${{ spiritsRevPerBottle.toFixed(2) }} revenue / bottle
1 case (24 units) at ${{ pourStandards.beer_packaged.avg_price }} avg = ${{ (pourStandards.beer_packaged.avg_price * 24).toFixed(2) }} revenue
Γ ${{ pourStandards.beer_draft.avg_price_per_pint }} = ${{ (Math.floor(15.5 * 128 / pourStandards.beer_draft.pint_oz) * pourStandards.beer_draft.avg_price_per_pint).toFixed(2) }} revenue
Portioned handles Received automatically β every invoice you import feeds this number. Sold is estimated from your Toast POS beverage revenue. The only thing staff need to do is the Closing Count β walk the bar and count what's actually there at the end of each month.
-
1Pulls received quantities from every invoice β PDF uploads and forwarded email invoices are the preferred source. Fintech CSV is used as a fallback. All sources feed into the same product list.The vendor's own invoice always wins over Fintech β it has the real SKU, pack size, and description.
-
2Estimates what was sold from Toast POS beverage revenue, divided by average selling price to estimate depletion.This is an approximation. Physical counts are what make the variance meaningful.
-
3Carries forward the closing count from last period as the opening count for the next one. Once you've done one full count, the system is self-maintaining.
-
4Flags variance by category β highlights when beer, wine, or spirits are depleting faster than sales can explain. Negative variance = missing product.
-
1Open the Count Sheet tab on your phone or tablet. The sheet is pre-filled with every product ordered in the last 60 days, organized by category.Products from invoices appear automatically once invoices are imported.
-
2Walk every storage area: walk-in cooler β back bar β front bar β dry storage. Count each product and enter the number of bottles (not cases).Partial bottles count as 0.5. Opened cases: count individual bottles.
-
3Tap Scan to use your camera β scan each bottle's barcode and it jumps to the right product row automatically. Or scroll and tap to enter counts manually.
-
4Hit Save Counts. The Variance Report updates instantly. Review with the manager and flag any categories showing more than 5% negative variance.
| When | Who | Task | Time |
|---|---|---|---|
| End-of-month close Last day of month |
Full bar count β all beverage storage areas. Open Count Sheet on tablet or phone, enter all counts, and hit Save before leaving. | 30β45 min | |
| After each delivery As needed |
Verify delivery against the invoice. Upload PDFs to Invoices tab. Fintech invoices sync automatically. Flag discrepancies in invoice notes. | 5β10 min | |
| Monthly review 1st of month |
Owner / Manager | Review the Variance Report for the closed period. Investigate any category with >5% negative variance. Note: the first period after setup is baseline only β variance reporting begins in period 2. | 15 min |
| Invoice import Ongoing |
Automatic | Fintech invoices sync automatically. PDF invoices: upload to Invoices tab when received. Email invoices: forward to your Portioned inbox address. | β |
Settings
π QuickBooks Online
Pull transactions automatically. Your accountant keeps full QBO access.
Stop exporting CSVs. Connect once and transactions sync automatically.
No imports yet.
Import Transactions from QuickBooks
Choose a date range. Portioned will skip anything already imported. Start date pre-filled to the day after your last import ({{ qboImportLog[0].end_date }}).
Fetching from QuickBooksβ¦
{{ qboImport.total > 0 ? `${qboImport.progress} / ${qboImport.total} transactions` : 'Connecting to QuickBooksβ¦' }}
Review Import
β New Transactions β Will Be Imported
β οΈ Possible Duplicates
Same amount, date within 5 days, different source. Skip keeps the existing CSV version. Replace with QB swaps it out (preserves your categorization). Import Both adds QB as a second transaction.
Saving transactionsβ¦
Compare QB Categories to Portioned
Portioned fetches transactions from QB for this period, matches them to your existing transactions by date & amount, and shows your category vs QB's category side-by-side. No transactions are imported.
Fetching from QuickBooksβ¦
Matching transactionsβ¦
Category Comparison
{{ qboCompare.results.length }} matched Β· {{ qboCompare.results.filter(r => r.differs).length }} differ Β· {{ qboCompare.unmatched.length }} QB transactions not found in Portioned
| Date | Description | Amount | Portioned Category | QB Category | |
|---|---|---|---|---|---|
| {{ r.portionedDate }} | {{ r.portionedDesc }} | ${{ Math.abs(r.portionedAmount).toFixed(2) }} | {{ r.portionedCategory || 'β' }} | {{ r.qboCategory }} | β Pushed β |
| No transactions match this filter. | |||||
QB Transactions Not in Portioned ({{ qboCompare.unmatched.length }})
These exist in QuickBooks but have no matching transaction in Portioned. Select any you want to import β Portioned rules will be applied automatically.
{{ qboMapping.state === 'saving' ? 'Saving mappingsβ¦' : 'Loading QB accountsβ¦' }}
{{ qboMapping.aiLoading ? 'AI is analyzing your chart of accountsβ¦' : 'Please waitβ¦' }}
QB Category Mappings
Match each Portioned category to a QB account. Used when pushing Portioned categories back to QuickBooks.
| Portioned Category | QB Account | Confidence | Note |
|---|---|---|---|
| {{ sug.portionedCat }} | {{ sug.confidence }} | {{ sug.note }} |
Mappings Saved
{{ Object.keys(qboMapping.savedMappings).length }} Portioned categories are now mapped to QB accounts. Use "Push to QB" in the Category Comparison view to sync categories.
βοΈ Dropbox Storage
Your financial data is stored in your own Dropbox account.
π Restaurant Context
Teach the bookkeeper AI permanent, business-specific context β vendor rules, seasonal patterns,
reporting preferences, owner notes. Saved as portioned.md in your Dropbox and
loaded into every AI session automatically.
Also editable directly in Dropbox at Apps/Portioned/portioned.md.
The AI reloads this file each time you open the Ask tab.
π Restaurant Context
Connect Dropbox to use this feature. Your context is stored in
Apps/Portioned/portioned.md and loaded into every AI session.
π₯οΈ Point of Sale
Connect your POS to automatically import daily revenue into your P&L.
Find these in Toast Admin β Integrations β Data Export β SFTP.
π§ Don't have SFTP access? Set up automatic email reports instead
Toast can automatically email you daily or monthly sales reports as CSV attachments β no SFTP credentials required.
- In Toast, go to Back of House β Reports β Scheduled Reports
- Click Add Scheduled Report
- Choose Sales Summary as the report type
- Set frequency to Daily (recommended) or Monthly
- Enter the email address where reports should be delivered
- Save β Toast will send the report automatically on your schedule
Once received, forward the email attachment to Portioned or import the CSV manually via Import Data β Toast Sales Summary. Full auto-import via email is coming soon.
Import Historical Data
Upload Toast Sales Summary exports to backfill past months. In Toast Back of House β Reports β Sales Summary, export by month and upload the zip files here. You can select multiple months at once.
π₯ Team Members
{{ activeRestaurant.name }} β manage who has access to your financial data.
| Name | Role | Last seen | Action | |
|---|---|---|---|---|
| {{ member.profiles?.full_name || 'β' }} | {{ member.profiles?.email || 'β' }} | {{ member.role }} | {{ member.last_seen_at ? formatRelativeTime(member.last_seen_at) : 'Never' }} | Owner |
| No members yet | ||||
Pending Invites
Owner Distribution Splits
Configure profit split percentages for each owner.
Total: {{ splitTotal }}% {{ splitTotal !== 100 ? '(must equal 100%)' : 'β' }}
Savings Reserve
Held back from profit before the split. The figure in force is frozen into each month you close, so changing it never restates a past payout.
Owner Transfers
Standing month-to-month shifts between owners, applied after the percentage split. Use this where the checks written differ from what the percentages say. A transfer only moves money between owners β it can never change the total distributed.
| From | To | Amount | From month | Until | Reason | Private | |
|---|---|---|---|---|---|---|---|
No owner transfers configured.
Accounting Method
Sets the basis for all P&L reports. Only account owners can change this.
Card & Account Ownership
Assign ownership to personal cards/accounts. Transactions from owned accounts are automatically flagged.
No accounts discovered yet. Upload some transaction files first.
| Bank/Source | Account | Display Name | Owner | Auto-Flag | From | Until |
|---|---|---|---|---|---|---|
| {{ acct.bank }} | {{ acct.accountDisplay }} |
Account Details
Optional reference info for each account. Stored locally β never uploaded.
No accounts discovered yet. Upload some transaction files first.
| Account | Full Account # | Routing # | Notes |
|---|---|---|---|
|
{{ accountDisplayName(acct.key, acct.bank, acct.account) }}
{{ acct.bank }}
|
Statement Periods
Configure billing cycle days for credit cards. Used for reconciliation to match statement periods instead of calendar months.
No accounts discovered yet. Upload some transaction files first.
| Bank/Source | Account | Statement Cycle Day | Enabled | Preview |
|---|---|---|---|---|
| {{ acct.bank }} | {{ acct.accountDisplay }} | {{ calculateStatementPeriod(statementPeriods[acct.key].cycleDay).label }} β |
Example: If your AMEX statement runs Nov 4 - Dec 3, enter "3" as the cycle day. When viewing December, the AMEX reconciliation card will automatically use the Nov 4 - Dec 3 period.
π‘ Tip: Check your credit card statement for the closing date (e.g., "Statement Closing Date: Dec 3"). Most bank accounts use calendar months (leave disabled).
π§ AI Skills
Skills add context to the AI bookkeeper β custom rules, venue type, labor handling, and more.
| Skill | Context | Active | |
|---|---|---|---|
|
{{ rs.skill.name }}
{{ rs.skill.description }}
|
{{ rs.skill.context }} |
No skills active yet. Browse the library to add some.
AI Settings
Configure AI-powered categorization using OpenRouter API.
Get your API key from openrouter.ai/keys.
Claude 3 Haiku achieved 85% accuracy in testing (8/10 perfect). Best for financial categorization. Cost: ~$0.25 per 1,000 transactions.
π§ Daily Report
Send a morning email with your key numbers β revenue, prime cost, uncategorized transactions, and more.
Sent every morning at 7am Eastern. Leave blank to use the owner's account email.
Describe what you want in the email and the AI will set it up for you.
π Push Notifications
Get notified on your device β daily P&L digest, anomaly alerts, and uncategorized reminders.
Each device you use must be opted in separately.
Business Profile
Configure your business information to improve AI categorization accuracy.
Used to show weather, school breaks, and city events in the P&L context panel.
Owners are automatically extracted from Account Ownership settings
Vendors with 3+ transactions are auto-detected. Add notes to provide context to AI.
Auto-detected from your transaction history
Re-generate business profile from current transactions and rules
Duplicate Detection History
The app tracks {{ Object.keys(transactionFingerprints).length }} previously imported transactions to detect duplicates. Clear this history if you want to start fresh (e.g., re-importing all data).
Manage Categories
Custom categories you've created. Remove ones you no longer need β a category can only be removed when no transactions still use it. Standard categories can't be removed.
No custom categories to manage.
| {{ cat.name }} | {{ cat.inUseCount }} transaction{{ cat.inUseCount === 1 ? '' : 's' }} |
π Migrate Data to Cloud
Import your existing bookkeeping data from the local app into Portioned v2. Your original data stays intact β this copies it into the cloud.
π {{ migration.counts.transactions }} transactions
π {{ migration.counts.rules }} rules
π {{ migration.counts.reconciliations }} reconciliations
πͺ {{ migration.counts.vendors }} vendors
β Migration complete!
{{ migration.result.transactions }} transactions imported. Your local data is still intact as a safety net.
β οΈ Clean Slate
Delete all transactions and start fresh. Your categorization rules will be preserved.
πΎ Backup & Restore
Protect your data with automatic and manual backups. All transactions, rules, and settings are included.
- β Auto-backup before every import (prevents data loss)
- β Background backup every 12 hours during work
- β Manual export anytime
- β Full restore from any backup
π Debug Logs
View error logs and debug information. Download logs to share with support.
| Time | Level | Message | Details |
|---|---|---|---|
| {{ formatLogTime(log.timestamp) }} | {{ log.level }} | View |
No logs to display. Logs will appear here when the app runs.