Excel Imports¶
| Status | Shipped |
|---|---|
| Linear | PIN-295 ↗ PIN-448 ↗ |
| Module | Smart Import ↗ |
Two places in the app parse spreadsheets into data rows: the Takeoff grid on a bid (Excel/CSV → takeoff quantity rows, parsed in the browser) and the Submittal log on a project (xlsx/CSV → submittal rows, parsed server-side, all-or-nothing). Everywhere else an
.xlsxis just stored as a document — uploading one to a Documents folder does not create data.
Prerequisites¶
- Role: Estimator or Chief Estimator for the takeoff import; PM for submittals.
- Bid state: a bid with an Estimate created (open the Estimate tab → Create Estimate if none).
- Test data:
estimates-xlsx/E25-1474 WNET 437 Madison Ave 3rd Fl.xlsx(duct) orE25-1500 Netflix 888 Broadway 3rd Fl.xlsx(pipe) from the test-app-files Drive folder.HVAC Bids Log.xlsxworks as a second sheet-picking exercise. - Permissions cached? Relogin if the Import button is missing.
1. Takeoff import — open the modal¶
Open a bid → Estimate tab → Takeoff sub-tab. In the toolbar, click Import (spreadsheet icon, tooltip "Import from Excel or CSV").
The modal Import Takeoff from Excel / CSV accepts .xlsx, .xlsm, .csv. Parsing happens entirely in the browser — nothing uploads until you confirm.
2. Pick a sheet and map columns¶
Select the file from estimates-xlsx/. The modal lets you:
- Pick a sheet — real estimate workbooks have several; try a non-first sheet (the E25-1474 workbook has 10,
Duct Takeoffis a good target). - Map columns — match spreadsheet columns to takeoff fields (Skip / Trade / Description / System / Size / Material / Quantity / Unit / Unit Cost / Spec Name / CSI Code / Notes / Drawing Ref).
- Choose mode — append new rows vs update existing.
A Trade (or System) column mapping is effectively required — verified live 2026-07-08: with no Trade mapped, Preview says "N valid" but the backend rejects every row (400) and the modal closes with zero rows and no error message. Silent-failure bug worth a ticket; until fixed, always map Trade.
Confirm. Rows land in the takeoff grid in batches (large files import in chunks of 500 — a many-hundred-row sheet is a good stress test).
3. Verify the takeoff grid¶
Spot-check a handful of imported rows against the spreadsheet: quantities, descriptions, no shifted columns. Re-import the same file in update mode and confirm it doesn't duplicate rows.
The import fills the takeoff quantity grid only — it does not create Estimate scope line items. Estimate rows are entered manually (or AI-assisted) in the Estimate grid. "I imported Excel but the Estimate is empty" is intended behavior, not a bug.
4. Submittal log import (project-side)¶
Open a project → Submittals tab → Import Submittals. Accepts a full submittal-log .xlsx (vendor, dates, status, lead time, shipping mapped) or a simple .csv / pasted rows.
- Parsing is server-side and all-or-nothing: one bad row rejects the whole file — verify a clear error message says why.
- There's no sample submittal log in the Drive folder yet — for a smoke test, paste 2–3 rows or make a minimal CSV (ask me for the expected columns).
Verification Checklist¶
- Import button is visible in the Takeoff toolbar for an Estimator
- Modal reads the xlsx in-browser, lists all sheets, and lets you map columns
- Imported row values match the source spreadsheet (no off-by-one column shifts)
- Re-import in update mode does not duplicate rows
- Submittal import: valid rows all land; an invalid file is rejected whole with a readable error
- No console errors during either import
Known Issues / Current Gaps¶
No xlsx bid import exists — bids come from manual creation, BuildingConnected/Procore sync, or SharePoint import (see doc 02, Priority 10). Don't test "import HVAC Bids Log as bids".
No takeoff→estimate auto-promotion from the import path — estimate lines stay manual/AI-assisted.
Related docs¶
- Takeoff — the measuring/markup flow that also feeds this grid
- Detailed Reference — Sample Project A — bid creation and document folders
Updating this walkthrough
Run the full flow yourself end-to-end. If it passes, bump last_verified: in the frontmatter to today's date. If any step fails, fix the doc or the code in the same PR — drift is the enemy.