Barform Docs
Open Barform (opens in a new tab)

Import from a spreadsheet

Load your menu, stock items and recipes from a CSV file — the columns each import reads, the check before anything is saved, and what gets created.

On this page

Settings › Import loads your menu, your stock items and your recipes from a spreadsheet. Every import is checked first and shows you, row by row, what it would do before anything is saved. Imports only add: an existing product or item with the same name, or an ingredient already on the recipe, is skipped, never changed. To bring your sales history over from TouchBistro, see Import TouchBistro history.

Who can do this: admins. The Import tab, and the Import button on Menu › Products, are shown to admins only.

Import a spreadsheet

  1. In the back office, go to Settings › Import (or click Import on Menu › Products). The page says "Load the menu, stock items and recipes from a spreadsheet. Every import is checked first and shows you what it would do, row by row, before anything is saved."
  2. Pick the tab: Menu (it opens first), Inventory items or Recipes. Starting from scratch, import them in that order: recipes need the products and the items to exist.
  3. Optional: click Download template. You get the header row and two example rows. The Columns box under the importer explains every column.
  4. Fill in the sheet and save it as CSV. In Excel, choose "CSV UTF-8". Excel's own .xlsx files aren't accepted.
  5. Click Choose a CSV and pick the file (.csv or .txt), or paste the rows into the box: "Or paste the rows here, header first:".
  6. Click Check file. The result says "Nothing has been saved yet." It shows badges such as 12 to import, 3 already there and 1 with problems, any notices, and a table with each row's Line, Row and What happens.
  7. If some rows have problems: "Rows with problems are left out — the rest still import. Fix them in the file and check again if you want them included." Fix the file and check again, or go on.
  8. Click Import {count} row(s). The button only appears after a check that found at least one row to import, and it disappears as soon as you change the text or choose another file.
  9. The result shows how many rows were imported, with "Imported {created}." or "Imported {created}, {failed} failed."
  10. To start again, click Clear.

Warning

There's no undo for these imports. Read the check carefully before you click Import.

Imported stock items and recipes are managed in Inventory and Menu › Recipes, which come with plans that include inventory (Plans and billing).

How the file is read

  • Separator: comma, semicolon or tab, read from the header row (whichever appears most). Files saved by a Spanish Excel, which uses semicolons, work.
  • Quotes: a value that contains the separator, a quote or a line break must be in double quotes. A quote inside a value is written twice ("").
  • Encoding: UTF-8. A file saved in another encoding shows accents wrongly.
  • Empty lines are skipped. A row made only of separators — what a spreadsheet writes for an empty row — is checked like any other row, refused, and left out.
  • A row with fewer cells than the header reads the missing cells as empty. A row with more is refused: "This row has {cells} columns but the header has {header}. A value probably contains a "{delimiter}" and needs wrapping in quotes."
  • Headers: columns can be in any order. Capitals, spaces, hyphens and accents don't matter ("Unit Cost" is read as unit_cost). Every column also answers to the Spanish names in the tables below, and a notice says what was read as what, for example: Read "producto" as name, "precio" as price. If a file has both our name and a Spanish name for the same column, ours wins and the other is ignored. Columns Barform doesn't know are ignored without a message.
  • Line in the result is the line in the file, counting the header as line 1 — the row number Excel shows, unless a cell contains a line break.
  • Up to 2,000 rows per file.
  • Names are matched ignoring capitals and spaces at either end, but accents count: "Limon" isn't "Limón". Archived products, items and categories are ignored when matching.
  • Import checks the file again at the moment you click it, so anything that changed since the check — someone adding the same product by hand, say — is caught then.
  • An import isn't all-or-nothing. If a row fails while importing, the others are still saved and the result names the row that failed.

If the file can't be read

  • "The file is empty."
  • "The first row must be a header row."
  • "The header has two "{column}" columns. Remove one."
  • "The file is missing {what}: {missing}. Expected: {expected}."
  • "The file has a header but no rows."
  • "That's {rows} rows; the limit is {limit} per import. Split the file."
  • "Could not read the file." — this also covers a quote that never closes.

Import the menu

Adds new products, each with a category and a price, and optionally a Spanish name, a description, a SKU and modifier groups. Categories and modifier groups that don't exist yet are created. Existing products are never changed. The tab says: "Adds products to the menu. Categories and modifier groups are matched by name; anything new is listed in the preview before it is created."

Column Required Also read as What to put
name Yes producto, product, nombre, articulo, bebida, item The product name as it will show on the iPad. Up to 120 characters.
name_es No nombre_es, nombre_espanol The Spanish name.
description No descripcion, detalle, notas A description, shown on the guest menu.
sku No clave, codigo, codigo_producto The product code.
category Yes categoria, familia, grupo, family, linea A category name. Created if it doesn't exist. Up to 120 characters.
price Yes precio, precio_venta, pvp, importe In pesos: 180, 180.50, 1,500.00 or 180,50; a $ is fine. From $0 to $1,000,000.
modifier_groups No modificadores, grupos_modificadores, grupos_de_modificadores Group names separated by semicolons (a comma or a vertical bar works too), e.g. Hielo; Guarnición. Groups that don't exist are created. Up to 120 characters each.

What a menu import does

  • "A product whose name already exists is skipped, never overwritten." Its row reads "A product with this name already exists — left untouched." Only live products count: a row with the name of an archived product creates a new product.
  • The check shows each row as its category and price, with "(new)" after a category that will be created, and how many modifier groups it gets.
  • Before you import, notices list what will be created, such as "Will create 2 category(ies): …" and "Will create 3 modifier group(s): …". Only categories and groups named on rows that will import are created, each once, spelled as it first appears.
  • Categories and groups are matched by name, ignoring capitals and spaces at the ends. A group named twice on one row counts once.
  • New categories go at the end of your category list, with no colour, No ticket (they print no prep ticket) and shown on the guest menu.
  • New modifier groups are created empty — no options — as optional groups where the guest picks at most one. Add their options in Menu › Modifiers (Modifiers). They sort among your first groups.
  • Imported products are on sale at once and reach every iPad within about a second. They go after your existing products, in file order, with no image and with Show on the guest menu on.
  • After importing, each row reads "Created." or "Created with {count} modifier group(s)."
  • If the new categories or groups can't be created, no product is imported: "Could not create the new categories: {error}" or "Could not create the new modifier groups: {error}". (Categories created before a group failed are kept.)
  • If the products are created but their groups can't be attached, the products stay: "Created, but its modifier groups could not be attached: {error}".
  • "Name is required." · "Name is longer than 120 characters."
  • "Category is required." · "Category name is longer than 120 characters."
  • "Price "{price}" isn't a number." — also for a negative price, or a price written 1.234,50. · "Price is above the {limit} limit."
  • "Modifier group name "{name}" is longer than 120 characters."
  • The same name twice in one file: the later row is refused with "The same name appears on line {line}. Remove one of them."

The menu import can't change existing products — use the product itself, or the bulk price update in Pricing — and it can't set an image, the Custom drink switch, availability, or a new category's colour, printer or guest-menu switch.

Import inventory items

Adds new stock items, each with a category, a unit and a unit cost, and optionally a Spanish name, SKU, barcode, container size, par level, reorder point, supplier and opening stock. Suppliers that don't exist yet are created. Existing items are never changed. The tab says: "Adds stock items. Opening quantities are posted as a stock movement, so they show up in the ledger like any other change."

Column Required Also read as What to put
name Yes articulo, insumo, producto, nombre, item The item name. Up to 120 characters.
name_es No nombre_es, nombre_espanol The Spanish name.
sku No clave, codigo The item code.
barcode No codigo_barras, codigo_de_barras One or more barcodes, 6 to 64 letters or digits each, separated by commas or semicolons.
category Yes categoria, familia, tipo One of spirit, beer, wine, mixer, garnish, food or consumable (any capitals).
unit Yes unidad, medida How it's stocked: oz, ml, each or g.
unit_cost Yes costo, costo_unitario, precio, precio_unitario The cost of ONE unit in pesos — per ml, per oz, per g or each. For example 0.3853 per ml for a $289 bottle of 750 ml. 1,500.50, 0,385 and a $ are fine.
container_size No presentacion, envase, tamano, contenido Free text, e.g. 750 ml bottle.
par_level No par, nivel_par, maximo The target to have on hand, in the unit. Default 0.
reorder_point No punto_reorden, reorden, minimo The low-stock threshold, in the unit. Default 0.
supplier No proveedor A supplier name. Created if it doesn't exist. Up to 120 characters.
opening_qty No existencia, existencias, inventario_inicial, cantidad_inicial, stock The stock on hand today, in the unit. Default 0.

Par level, reorder point and opening stock read numbers the way the back office does: 1,500 is fifteen hundred, and 2,5 is two and a half. A figure that could mean either, such as 1,50.0, is refused with the column's range message rather than guessed.

What an items import does

  • "An item whose name already exists is skipped, never overwritten." Its row reads "An item with this name already exists — left untouched." Only live items count.
  • Category and unit must be one of the English codes above; they're never created. Spanish words such as destilado or pza are refused.
  • The unit cost is saved as the item's cost, and as its last price paid until a delivery says otherwise. See Items and stock.
  • Par level, reorder point and opening stock go from 0 to 1,000,000. Opening stock is rounded to three decimals.
  • Opening stock is recorded as a stock movement with the reason Count correction, in your name, so it shows in Inventory › Activity. If that can't be recorded, the item isn't kept: "Opening stock could not be recorded, so the item was not kept: {error}".
  • Barcodes are added once the item exists, with the same rules as the Items page. A bad or taken barcode costs only the barcode, never the item, and a notice names the line: for example "Line {line}: {code} is already on {item}, so it was not added."
  • Bottle weights are filled in from Barform's shared catalogue where an item matches: "{n} bottle weight(s) filled from the shared catalogue — check them on the Items page."
  • New suppliers get their name, and Their prices include IVA set the way your venue's Received prices include IVA is set in Settings › Venue. Before you import: "Will create {count} supplier(s): {names}."
  • The check shows each row as its category, unit and cost, and its opening stock or "no opening stock". After importing, each row reads "Created." or "Created with {qty} {unit} opening stock."
  • Container size is kept as typed; the import doesn't create item sizes.

Item rows that are refused

  • "Category must be one of: {allowed}." · "Unit must be one of: {allowed}."
  • "Unit cost "{cost}" isn't a number." — also for a negative cost. · "Unit cost is above the {limit} limit."
  • "Par level "{value}" must be a number between 0 and 1,000,000." — and the same for the reorder point and the opening quantity.
  • "Supplier name is longer than 120 characters."
  • The same name twice in one file: "The same name appears on line {line}. Remove one of them."
  • If the new suppliers can't be created, no item is imported: "Could not create the new suppliers: {error}".

The items import can't set item sizes, weights or whether an item is active, and it can't change existing items.

Import recipes

Builds recipes from one row per ingredient: the rows that name the same product make that product's recipe. It adds ingredients to an existing recipe, but never changes or removes one that's already there. The tab says: "One row per ingredient. Rows sharing a product name build that product's recipe, so import the menu and the items first."

Column Required Also read as What to put
product Yes producto, bebida The name of an existing product.
item Yes insumo, articulo, ingrediente The name of an existing inventory item.
quantity Yes cantidad, qty How much of the item the recipe uses — for the whole batch when yields is more than 1. More than 0, up to 1,000,000.
unit Yes unidad, medida oz, ml, each, dash or g. It must measure the same kind of thing as the item's own unit.
yields No rendimiento, porciones Servings per batch: a whole number from 1 to 10,000. Default 1. Must be the same on all of a product's rows.
notes No notas, nota, observaciones Notes for the recipe (not for the line).

Quantity and yields read numbers the way the back office does: 1,000 is a thousand, and 1,5 is one and a half. A figure that could mean either is refused rather than guessed.

What a recipes import does

  • Neither products nor items are created: "No product called "{name}". Import the menu first, or fix the spelling." and "No inventory item called "{name}". Import items first, or fix the spelling."
  • Units are matched by kind: oz, ml and dash measure volume, g measures weight, each counts. A line whose unit can't measure the item is refused: "A "{unit}" ({dimension}) quantity can't measure "{item}", stocked in "{itemUnit}" ({itemDimension}). Use a {suggest} unit."
  • "An item already on a product's recipe is skipped. An existing recipe keeps its own yields and notes." Its row reads "Already an ingredient of this recipe — left untouched." The same item twice for one product in the file is refused: "This item is already on this product's recipe at line {line}. Remove one."
  • A new recipe takes its yield from the file (1 if empty) and its notes from the first of that product's rows that has notes, up to 2,000 characters.
  • The check shows each row as its quantity and unit, plus "new recipe" or "added to the existing recipe". After importing: "Added {qty} {unit}."
  • Once a product has a recipe, paying a check with it takes the ingredients off stock. See Recipes and wells.

Recipe rows that are refused

  • "Product is required." · "Item is required."
  • "Quantity "{qty}" isn't a number." · "Quantity must be greater than zero." · "Quantity is above the 1,000,000 limit."
  • "Unit must be one of: {allowed}."
  • "Yields "{value}" must be a whole number between 1 and 10,000." · "Yields is {here} here but {there} on line {line}. They must agree."
  • If a recipe can't be created, all its rows fail: "Could not create the recipe: {error}".

The recipes import can't set the line options of Menu › Recipes, such as swaps and wells: set those in Menu › Recipes.

Search for a task or a screen: charge, tip, close the day…