How It Works

Complete calculation guide

How It Works

Invoices & Revenue

Invoice Total Calculation

An invoice's total is calculated in this order:

Subtotal = SUM(item.quantity × item.unitPrice)
After Discount = Subtotal − (Subtotal × discount%)
Tax = After Discount × (tax rate / 100)
Total = After Discount + Tax + Fees

Example: 2 items @ $100 each = $200 subtotal, 10% discount = $180, 19% tax on $180 = $34.20, +$5 fee = $219.20 total

Payment Tracking

Payments are applied individually to invoices:

Amount Paid = Sum of all payments applied
Remaining Balance = Total − Amount Paid
Status (auto-updated):
draft → Not sent to client
sent → Sent but not paid
partially_paid → 0 < Paid < Total
paid → Paid ≥ Total
overdue → Due date passed, unpaid

Overpayment → Client Balance

When a payment exceeds the remaining invoice balance, the excess is automatically added to the client's credit balance:

Applied to Invoice = min(Payment Amount, Remaining Balance)
Excess = Payment Amount − Applied to Invoice
Client Balance += Excess

Example: Invoice total = $200, already paid $150, remaining = $50. Client pays $80 → $50 applied to invoice (status → paid), $30 added to client balance.

The client's balance is then auto-applied to future invoices at creation time.

Cost of Goods Sold (COGS)

Product costs are snapshotted at invoice creation time:

• Each item records unitCost at creation
Item COGS = unitCost × quantity
Invoice COGS = Sum of all item COGS
• Used in profit calculations, never changes

Automatic Balance Application

When a client has an outstanding balance (from overpayments), it automatically applies to new invoices. If new invoice = $500 and client balance = $100, the client owes only $400.

Clients & Payments

Client Balance Tracking

A client's balance is tracked cumulatively:

Total Invoiced = Sum of all invoice totals
Total Paid = Sum of all payments applied
Pending Balance = Amount owed without invoices (e.g. from Excel imports)
Total Pending = (Total Invoiced − Total Paid) + Pending Balance
Client Balance = Available credit from overpayments

Bulk Payment Distribution (FIFO)

Payments are distributed in 3 priority steps:

  1. Invoices first: Apply to unpaid invoices, oldest first (FIFO)
  2. Pending Balance: If remaining, reduce the client's pending balance (imported amounts with no invoices)
  3. Credit Balance: Any remaining excess goes to client credit balance

Example: Invoice 1: $500 unpaid, Pending Balance: $200. Client pays $800 → Invoice 1 fully paid ($500), Pending Balance reduced by $200, Client Balance += $100.

Stock & Inventory

Stock Quantity Tracking

Stock is tracked differently for simple and composite products:

Simple Products: Quantity is stored directly
Composite Products: Effective Qty = floor(min(component1_available / component1_needed, ...))

Example: Chair (composite) needs 1 frame + 4 wheels. Available: 10 frames, 32 wheels → Effective qty = floor(min(10/1, 32/4)) = floor(min(10, 8)) = 8 chairs

Low Stock Alerts

Products are flagged as low stock when: Effective Quantity ≤ Minimum Stock (default minStock = 5)

Stock Deduction on Invoice

When an invoice is created:

  1. Validation: Check sufficient stock exists BEFORE allowing creation
  2. Deduction: After invoice saved, subtract from stock
  3. Simple: quantity -= item.quantity
  4. Composite: For each component, quantity -= (component.quantity_needed × item.quantity)

⚠️ Stock deduction is atomic: If validation passes, deduction WILL succeed. If validation fails, invoice creation is blocked entirely.

Automatic SKU Generation

SKUs are auto-generated during creation or category change:

SKU = [Category Prefix] + [Sequence Number]

Example: Category "Furniture" with 3 existing products → new product gets SKU "Furniture-4"

Expenses & Recurring Charges

One-Time Expenses

Fixed amount expenses included in reports only if date is within report period. No pro-ration applied.

Recurring Expenses

Stored as a rate and pro-rated based on recurrence pattern:

RecurrenceFormulaExample
Weeklyrate × (days ÷ 7)$100/week × 10 days = $142.86
Monthlyrate × months (calendar-accurate)$1000/month × 1.5 months = $1500
Quarterlyrate × (months ÷ 3)$3000/quarter × 2 months = $2000
Yearlyrate × (days ÷ 365)$12000/year × 100 days = $3287.67

Calendar-Accurate Month Calculation

When you have a monthly expense or salary, the system needs to figure out how many months fit between two dates. Instead of assuming every month has 30 days, it counts using the real calendar.

The idea is simple: split the date range into 3 parts:

1. Remaining days in the first month — how much of the starting month is left?
2. Full months in between — any complete months from start to end?
3. Days used in the last month — how far into the ending month?

Example: Feb 15 → Mar 17 (expense is $1,000/month)

Step 1 — Rest of February: Feb has 28 days. From Feb 15 to Feb 28 = 14 days remaining.
14 ÷ 28 = 0.5 (half a month)
Step 2 — Full months between: Feb and Mar are next to each other, so there are 0 full months in between.
Step 3 — Days used in March: 17 days into March. March has 31 days.
17 ÷ 31 = 0.5484 months
Total = 0.5 + 0 + 0.5484 = 1.0484 months → $1,000 × 1.0484 = $1,048.40

Another example: Jan 1 → Mar 31

Step 1: Jan 1 to Jan 31 = full month → 1.0
Step 2: February is one full month in between → 1.0
Step 3: Mar 1 to Mar 31 = full month → 31 ÷ 31 = 1.0
Total = 1.0 + 1.0 + 1.0 = 3.0 months exactly
Rounding difference between reports:
P&L Report: Uses the exact number (e.g. 1.0484 months)
Comprehensive Report: Rounds to the nearest whole month (e.g. 1.0484 → 1 month)

Employees & Payroll

Salary Calculation by Period

Base salary is calculated differently by employee's salary period:

Weekly

Salary = rate × (days ÷ 7)

$1000/week, 21 days (3 weeks) = $3000

Monthly

Salary = rate × calcMonths() [calendar-accurate]

$3000/month, Feb 15–Mar 17 (1.0484 months) = $3145.20

Salary Advances: Deduction & Pro-rating

Advances reduce take-home pay, pro-rated by overlap between the advance's pay period and the report period:

Remaining Days = calcDays(Advance Date, Period End)
Daily Rate = Advance Amount ÷ Remaining Days
Overlap Days = calcDays(max(Advance Date, Report Start), min(Period End, Report End))
Deduction = Daily Rate × Overlap Days
Net Salary = Base Salary − Sum of Deductions

Example: $3000/month employee, $500 advance on Jan 25. Period end = Jan 31. Remaining days = calcDays(Jan 25, Jan 31) = 7. Daily rate = $500 ÷ 7 = $71.43. If report covers full January: overlap = 7 days → Deduction = $71.43 × 7 = $500. Net salary: $3000 − $500 = $2500.

If report only covers Jan 25–Jan 28 (4 overlap days): Deduction = $71.43 × 4 = $285.71.

Advance Status & What Each Means

Every salary advance has one of 3 statuses:

Pending — The advance was given but the pay period hasn't ended yet. It will be deducted from the employee's salary.
Deducted from Salary — The pay period has ended and the advance was automatically deducted from salary. This happens on its own — you don't need to do anything.
Returned — The employee gave back the money directly (not through salary). The advance is NOT deducted from salary.

When does it auto-change to "Deducted"?

Weekly employee → when a new week starts after the advance
Monthly employee → when a new month starts after the advance

What can you change manually?

• You can mark a Pending advance as Returned (employee gave the money back) — it will no longer be deducted from salary
• You can switch a Returned advance back to Pending if needed
• Once an advance is Deducted from Salary, you cannot change it — it's already been applied

Employee Inactive Date

Employees can have an inactive date that stops salary calculation from that date:

• If inactiveDate is set, salary is only calculated up to that date
• The salary end date = min(inactiveDate, report end date)
• If inactiveDate is before the report start date, the employee is excluded entirely
• This applies to both P&L and Comprehensive report salary calculations
• Dashboard earnings also respect the inactive date

Example: Employee earns $3,000/month, hired Jan 1, inactive date = Feb 15. For a Jan 1 – Mar 31 report: salary is calculated for Jan 1 – Feb 15 only (1.5 months = $4,500), not the full 3 months.

Supplier Bills & Payables

Bill Type

Each supplier bill has a type that determines how it is treated in financial calculations:

Stock / Inventory — The bill is for purchasing stock or raw materials.This cost is already reflected in COGS when products are sold, so it is NOT included in operating expenses. This avoids double-counting.
Operating Expense — The bill is for services, rent, utilities, or other operational costs.This IS included in operating expenses on reports, dashboard, and expense listings.

Bill Payment Tracking

Similar to invoices, supplier bills track:

Bill Amount = Stored at creation
Amount Paid = Sum of all payments
Remaining = Bill Amount − Amount Paid
Status: pending (0%), partially_paid (0–100%), paid (100%)

Days Overdue

daysOverdue = floor((now − dueDate) ÷ 86400000)

Aging categories: Current (0 days), 1-30, 31-60, 61-90, 90+

Excel Import

Client Import

Import clients in bulk from an Excel or CSV file. Supported columns:

name (required) — Client name
email, phone — Contact details (duplicates within the org are skipped)
address, city, country — Location info
balance — Credit balance (overpayment credits)
pending — Pending balance (amount owed without invoices)
notes — Free text notes
• Rows with duplicate email or phone (within the org) are skipped with a reason
• Rows without a name are skipped
• The balance column sets the client's credit balance directly
• The pending column sets the client's pendingBalance — this is included in totalPending calculations and can be reduced via bulk payments

Supplier Import

Import suppliers in bulk from an Excel or CSV file. Only details are imported — no bills are created. Supported columns:

name (required) — Supplier name
contact_name — Contact person
��� email, phone — Contact details (duplicate emails are skipped)
address, city, country — Location info
payment_terms — Payment terms in days
notes — Free text notes

Import Behavior

• Column headers are case-insensitive and spaces/underscores are normalized
• Alternative column names are supported (e.g. "supplier_name", "contact", "telephone", "mobile")
• After import, a summary shows: count imported, count skipped, and details for each skip
• All imports are logged in the Activity Log

Tax Calculations

Tax per Invoice

Tax is calculated on the discounted amount:

Tax = (Subtotal − Discount) × (Tax Rate ÷ 100)

Default tax rate: 19%

Tax Collection Tracking

Total Tax: Sum of tax from all invoices regardless of status (draft, sent, partially paid, paid)
• Tax is treated like COGS — it is recognized in full at invoice creation, not pro-rated by payment

Tax in P&L Reports

Tax is calculated on all invoices within the report period:

Tax Collected = SUM(invoice.tax) for all invoices in period

Example: 3 invoices in January — $190 tax (paid), $95 tax (partially paid), $50 tax (draft) → Total tax = $335

Financial Reports

Profit & Loss (P&L) Report

Calculates profitability over a date range.

Revenue = SUM(payments in period) [cash basis]
COGS = SUM(unitCost × qty) for invoices with payments in period
Tax = SUM(invoice.tax) for all invoices in period [full amount regardless of payment status]
Gross Profit = Revenue − COGS
Total Expenses = one-time + recurring + salary + bills
Net Profit = Gross Profit − Expenses

Balance Sheet Report

Snapshot of financial position.

Assets: Cash + Accounts Receivable + Inventory
Liabilities: Tax Payable (full tax from all invoices)
Equity: Total Assets − Total Liabilities

Comprehensive Report

Combines P&L with detailed breakdowns:

  • Revenue breakdown (period vs. old invoices)
  • COGS by invoice with gross profit
  • Receivable aging (by days overdue)
  • Payable aging (supplier bills)
  • Profit margins (COGS, Gross, Net)

Cash Out (Total Sales Section)

Both P&L and Comprehensive reports include a "Total Sales in Period" section with a Cash Out metric:

Cash Out = One-Time Expenses + All Supplier Bill Payments
Net Profit (Sales) = Total Paid − Cash Out
One-Time Expenses: Only expenses with recurrence = "none" (no recurring, no salaries)
Supplier Bill Payments: All types (both stock and expense bills)
Excluded: Recurring expenses and salaries — these are estimated/prorated amounts, not actual one-time payments

Why? Cash Out shows what you actually paid out as discrete payments, so you can compare it to the cash received (Total Paid) to see real cash flow.

Profit Margins

COGS Margin = (Total COGS ÷ Revenue) × 100
Gross Margin = (Gross Profit ÷ Revenue) × 100
Net Margin = (Net Profit ÷ Revenue) × 100

Dashboard KPIs

Earnings Summary

Gross Earning: Sum of all invoice totals
COGS: Sum of (unitCost × qty) for all invoiced items
Total Tax: Sum of tax across all invoices
Total Supplier Bills: Sum of all bill amounts
Total Expenses: Sum of one-time + recurring
Total Salaries: All employees prorated from hire date to today (minus advances)
Net Earning: Gross − COGS − Tax − Bills − Expenses − Salaries
Pending Amount: Sum of unpaid invoice balances

Revenue Trend

Groups invoices by month (12-month lookback):

Trend % = ((current month − prior month) ÷ prior month) × 100

Green indicates positive trend, red indicates negative.

New This Month

Counts new clients and invoices created after month start.

Low Stock Products

Lists products where Effective Quantity ≤ Minimum Stock Threshold.

Data Integrity & Validation

Invoice Creation Validation

  • Client must exist
  • At least one invoice item required
  • Item quantity > 0
  • Product must exist with sufficient stock
  • Item unit price must be ≥ product cost
  • Invoice date must be valid
  • Tax rate (if provided) must be 0–100%

⚠️ If validation fails, invoice is NOT created and error is shown.

Rounding & Precision

Value TypeFormatExample
Currency2 decimals with symbol$1,234.56
Percentage1 decimal place19.5%
Month (pro-ration)4 decimals (internal)1.5048
DaysInteger (floor)30
Quantity2 decimals or integer5 or 2.5

Payment Boundary Checks

  • Payment amount must be greater than 0
  • If payment exceeds remaining balance, only the remaining is applied to the invoice — excess goes to client balance
  • Invoice payment records never exceed the invoice total
  • Client balance auto-applies to new invoices at creation

Audit Trail

All actions are logged in Activity Log: invoice creation/update/delete, payments, expenses, stock adjustments, employee changes, advances.

Frequently Asked Questions