Data Import — User Guide
Import master data (brands, categories, products, customers, locations, opening inventory) from Excel (.xlsx, .xls) or CSV files.
Document version: 1.0 · Last updated: 2026-02
Overview
The Data Import module lets you bulk-load:
- Master data: Brands, categories, colors, sizes, styles, models, products, customers, suppliers, locations
- Pricing: Price lists, price list scopes, price list items
- Go-live: Opening inventory (quantities per product and location)
Import flow: Download template → Upload file → Map columns → Preview → Run import
Template Usage
- Go to Data Imports → select the import type (e.g. Brands, Products).
- Click Download template to get an Excel file with the expected columns.
- Fill the template with your data. Use the exact column names from row 1.
- Save as Excel (.xlsx, .xls) or CSV (.csv).
Supported formats
- Excel:
.xlsx,.xls— first sheet, first row as headers - CSV:
.csv— UTF-8, first row as headers
Limits
- Max file size: 10 MB
- Max rows: 50,000
- Encoding: UTF-8 for CSV
Column Mapping
After uploading, map your file columns to the target fields:
- Source columns (left): headers from your file
- Target fields (right): schema fields for the import type
- Use Skip for columns you don't want to import
The preview shows the first 20 rows with your mapping applied. Fix mapping before running.
Import Types and Required Fields
| Type | Required | Notes |
|---|---|---|
| Brand | name | Optional: code |
| Category | name | Optional: parentName, code |
| Color | name | Optional: code, hex |
| Size | name | Optional: code, sortOrder |
| Style | name | Optional: code, brandName |
| Model | name | Optional: code, brandName |
| Product | name, sku, category, unitOfMeasure | Optional: barcode, brand, color, size, style, model, price, cost, currency, description, taxes, isActive |
| Customer | name or (firstName + lastName) | Optional: email, phone, taxId, taxName, customerCode, address, city, country, creditLimit |
| Employee | fullName | Optional: employeeNumber, email, phone, locationName, userEmail, position, department, employmentType (full_time/part_time/contractor/seasonal/intern), hireDate, terminationDate, commissionRate, hourlyRate, salaryAmount, tipPoolShare, serverNumber, canTakeOrders, canCloseTables, maxTableCapacity, salesTargetMonthly, canProcessReturns, defaultShift, worksWeekends, isActive, isManager, canApproveReturns, canApproveDiscounts, canApproveVoids, canOverridePrices, notes |
| Supplier | name | Optional: supplierCode, email, phone, taxId, taxName, taxAddress, address, city, postalCode, country, stateName, departmentName, municipalityName, taxpayerType, isActive |
| Location | name | Optional: timezone, taxNumber, availableToSell, availableToBuy, isActive. Optional address: lineOne, lineTwo, postalCode, municipality, department, countryId (if any address field is provided, lineOne is required; countryId defaults to GT). |
| Price List | name, currency | Optional: kind (retail/restaurant/both), channel (pos/online/dine_in/takeaway/delivery/kiosk/wholesale), priority, validFrom, validTo, isActive, notes |
| Price List Scope | priceListName, channel | Optional: locationName (null = global), isDefault, isActive |
| Price List Item | priceListName, itemType, itemIdentifier, unitPrice | Optional: minQty, priority, validFrom, validTo, isActive. itemType: product/service/modifier. itemIdentifier: SKU (product), name (service/modifier) |
| Opening inventory | sku, location, quantity | Optional: cost |
References: Product import requires categories, brands, colors, etc. to exist. Import catalogs (brand, category, etc.) before products. Price list imports require currencies and (optionally) locations. Price list item imports require price lists and products/services/modifiers.
Product taxes (optional column)
The taxes column controls which taxes are applied to each product:
| Value | Meaning |
|---|---|
| (empty) | New products: use the business default product taxes (same as creating a product in the app). Updates: do not change existing taxes. |
none, n/a, - | No taxes for this product. |
| Tax code(s) | One or more taxes by code or name, separated by |. Use the code or name of taxes linked to your business. |
| Code with rate | Override the default rate: code:rate (e.g. IVA:12). Multiple: IVA:12|ISR:5. |
Examples: IVA (one tax, default rate), IVA\|ISR (two taxes), IVA:12 (IVA at 12%), IVA:12.5\|ISR (IVA at 12.5%, ISR at definition rate). Taxes must exist and be linked to the business (Tax settings).
Errors and Partial Success
- Each row is processed independently. Invalid rows are skipped and reported; valid rows are committed.
- When the import finishes, you get: total rows, success count, error count.
- Download errors: Get a CSV with row numbers, error messages, and original row data to fix and re-import.
Common errors
- Missing required field — Add the column or value.
- Category/Brand/Color not found — Import that catalog first or fix the name.
- Product/Location not found (opening inventory) — Ensure product and location exist and belong to the business.
- Unit of measure required (product) — Add unitOfMeasure; no fallback in MVP.
- Tax 'X' not found (product) — The value in the taxes column must match a tax code or name linked to the business. Create and link the tax in Tax settings first.
- When address is provided, lineOne is required (location) — Map at least lineOne if you map any address field (postalCode, municipality, etc.).
- Country 'X' could not be resolved (location) — Use ISO code (e.g. GT, US) or full name (e.g. Guatemala) for the countryId column.
- Location 'X' not found (employee) — Import locations first or fix the locationName value.
- User with email 'X' not found (employee) — The userEmail must match an existing system user. Leave empty if the employee doesn't need system access.
- employmentType must be one of: ... (employee) — Use one of: full_time, part_time, contractor, seasonal, intern.
Opening Inventory — Important
Opening inventory replaces existing stock for the given product + location (absolute set). Use only for:
- Initial go-live setup
- Intentional corrections
The wizard shows a warning and requires you to acknowledge before running. Re-importing a corrected file will overwrite quantities again; it will not duplicate ledger entries for the same product+location.
API Reference
Endpoints are documented in Swagger at /api when the backend is running:
POST /data-import/upload— Create import jobGET /data-import/jobs— List jobsGET /data-import/jobs/:id— Job statusGET /data-import/jobs/:id/errors— Error rows (JSON or?format=csv)POST /data-import/preview— Preview mapped rowsGET /data-import/templates/:importType— Download template