Import / Export Module
Importing & Exporting Data
Bring historical records in from a spreadsheet or another system via CSV, or pull what’s already here back out — a guided, four-step wizard for imports, a one-click download for exports.
Start here
1Before you start
Thirteen kinds of record can be imported, and most of them reference another one by name — a Sales Invoice references a Customer, a Stock Level references a Product and a Warehouse. Anything a file references has to already exist before you import that file; a referenced record can’t appear later in the same import (the one exception is Accounts’ own Parent Account Code, which can point at an earlier row in the same file).
The recommended order:
Accounts → Contacts → Products → Warehouses → Employees → then Income / Expenses / Bank Transactions / Sales Invoices / Purchase Bills / Salaries / Stock Levels / Transfers, in any order relative to each other.
Create your bank accounts directly in Banking first — nothing here can create one.
Import a file
2Choose what to import
Pick the record type from Import Into. The required and optional columns for that type appear immediately below it — click Download CSV Template for a blank file with exactly those headers already in place. Then upload your CSV file.
Column headers don’t need to match exactly — auto-detect handles close matches in the next step, and anything else can be mapped by hand.
3Match your columns
Line each column in your file up against the field it corresponds to. For a grouped entity (Sales Invoices, Purchase Bills — see below) you’ll map header fields and line-item fields separately; header values are expected to repeat identically on every row belonging to the same invoice or bill.
4Preview & validate
A dry run — nothing is created yet. Every row is checked against the same rules the real import will use: required fields, valid numbers, and every cross-reference (a bank account name, a customer, a SKU) actually resolving to a real record.
Rows with errors are listed with the specific reason. Fix your file and re-upload, or move on and import only the rows that are already valid — invalid rows are simply skipped, not blocking.
5Import the valid rows
Click Import N Rows. Each row is created through the exact same real save logic its target module’s own form uses — so every default, validation rule, and side effect that would apply to typing it in by hand still applies here.
This runs row by row, not as one transaction — a row that fails at this stage (for a reason validation couldn’t predict, like a duplicate account code) doesn’t block any of the others. You get a final count of records created and records skipped, with the reason for each skip.
Export data
6Download existing data as CSV
The separate Export existing data panel is always visible alongside the import wizard. Pick what you want and click Export CSV — it downloads immediately, built directly from what’s already stored for the active company.
Most import entities can be exported the same way, with one difference worth knowing: an exported Employees file leaves the four compensation columns blank, since pay history lives in a separate record, not as flat fields on the employee.
Common tasks
Migrating a whole company’s history
Bringing over years of records from another system.
Import your foundation records first
Accounts, Contacts, Products, Warehouses, Employees — in that order, since almost everything after references one of these.
Import your transactional history
Income, Expenses (or the unified Bank Transactions if your old system exports both together), Sales Invoices, Purchase Bills, Salaries, Stock Levels, and Transfers — these can go in any order relative to each other.
Choose safe statuses for historical rows
For Purchase Bills, “billed” is usually the right default for old records rather than “received” — “received” can trigger a real Inventory stock movement if a line resolves to a Product with a Warehouse mapped, which you may not want for history that’s already accounted for elsewhere.
Reconcile stock last
Import Stock Levels after Products and Warehouses exist — it sets each product’s on-hand quantity per warehouse as an absolute count, not an addition, so it’s safe to re-run if a number needs correcting.
Importing invoices or bills with line items
Sales Invoices and Purchase Bills are grouped entities — one CSV row per line item, not per invoice. Every row belonging to the same invoice repeats the same Invoice Number (or PO / Bill Number) and the same header fields (customer/vendor, dates, status); only the line-specific columns (description, quantity, unit price) differ row to row. This is the same shape most accounting systems’ own invoice-and-line exports already use, so a direct export from your old system often maps in with little rework.
Avoiding double-counted transfers
If you’re importing both a Transfers file and a Bank Transactions / Income / Expenses file from the same source, the same real-world transfer can appear in both — once as a transfer, once as a bank movement on each side. Check for matching reference numbers between the two files first and import only one side of each; this isn’t detected automatically, and importing both double-counts the movement.
Reference
What can be imported
| Entity | Shape | Notes |
|---|---|---|
| Contacts | Flat | Customers, vendors, leads, employees, or other. |
| Products | Flat | Product, service, or bundle. |
| Accounts | Flat | Chart of Accounts — Parent Account Code can reference an earlier row in the same file. |
| Warehouses | Flat | |
| Employees | Flat | Leaving Employee Code blank creates a new employee; a code matching an existing employee overwrites that record instead. |
| Income / Expenses | Flat | Real Banking transactions — separate files, mirroring most exports. |
| Bank Transactions | Flat | A unified Income + Expense file with a Type column, for systems that export both together. |
| Sales Invoices / Purchase Bills | Grouped | One row per line item — see above. |
| Salaries | Flat | Payslip history only — creates no GL journal or cash movement (see below). |
| Stock Levels | Flat | Sets an absolute on-hand quantity per product/warehouse, not an addition. |
| Transfers | Flat | Moves both account balances immediately, even at “pending” status. |
What this module doesn’t do
Every import creates new rows. The only exceptions: an Employee Code matching an existing employee overwrites that employee, and a Stock Level for a product/warehouse pair that already has one updates it in place. Everything else creates a duplicate if you import the same file twice.
There’s no bulk “undo this import” — a bad commit has to be cleaned up by deleting the created records individually in their own module.
Importing payslip history is a plain record insert — it never posts to the ledger or moves cash, unlike a real Payroll run’s Approve & Post. Historical cash movement is expected to come from a separately-imported Bank Transactions/Transfers file, so this deliberately doesn’t double up on that.
Their stored shape doesn’t map cleanly back to the flat CSV format (stock is keyed by warehouse ID, payroll rows have no single “amount” field, and Bank Transactions would just re-export the same rows Income/Expenses already cover).