Month at a glance —
This month, the year so far, and the same period last year
In the shop right now
In cleaning0
Ready for delivery0
Rugs stay on this board until you mark them delivered. Days counted from the intake date.
Revenue and net profit by month
About this app
Version 1.6, built 25 July 2026.
What has changed
- Fixed: on a cleaning order with more than one rug, Rug shield $/sq ft was being charged against every rug's combined size, even if only one rug actually needed it. Each rug now has its own "Apply rug shield" checkbox — rug 1 starts checked (so a single-rug order behaves exactly as before), and each additional rug starts unchecked, so you pick which ones actually get it. The shield rate itself is still set once for the whole order.
- Adding records from a file now also adds any Category it uses that isn't already in Settings — so an imported Expense or Other Income/Cost with a new category shows up correctly and is pickable in its own edit form right away, instead of needing the category added by hand afterward.
- Fixed: applying a return's credit to another order, and the notes it adds on both orders, showed a doubled "##" in front of order numbers that already had their own "#" (e.g. from a Shopify import). Order numbers now always show exactly one.
- Applying a return's credit now confirms exactly what happened — including the destination order number and its date — in the confirmation message, since that other order might be dated outside whatever month or range the Rug Sales table is currently showing, so its row (and the credit note on it) may not be visible without switching to Year to date or a custom range that covers it.
- If the order being credited is still priced at less than the credit amount — a sign its Price hasn't been updated to its true full value yet — you're now asked to confirm before the credit is applied, instead of it silently leaving that order looking overpaid.
- A return can now be applied as credit to a different order instead of refunded — for an exchange or upgrade, e.g. a returned rug's value put toward a larger one. Pick the other order and the amount when marking the return; that amount is added to the other order's Received so its balance and Paid status come out right, without inflating or losing total sales and costs. Both orders show the link (the return shows where the credit went, the order that received it shows where it came from), and the Returns report lists it too. Editing or undoing a return reverses the credit cleanly.
- A rug's notes now show under its description in the Rug Sales list, so they're visible at a glance instead of only inside the form. Rows without notes look exactly as before.
- Added a Notes field for each rug on a Rug Sale — the main rug and every additional rug now has its own notes (condition, requests, anything specific to that piece), separate from the whole-order Notes field.
- Fixed: on a table with several row actions (Edit, Return, Move to…, Delete), those buttons could run off the right edge of the screen with no way to reach them. The actions now stay pinned to the visible edge of the table as you scroll it sideways, instead of scrolling away with the rest of the columns.
- Rug Sales can now include a rug pad, priced at $/sq ft against that same rug's own size — no need to re-enter dimensions. Works on the main rug and on each additional rug in a multi-rug sale, and shows as its own line on the invoice.
- "Other Work" is now called "Rug Repairs" throughout the app.
- Added a Return button on Rug Sales, alongside Edit and Move to. Marking a sale as returned records the date and reason, puts any linked inventory rug back in stock, and removes it from revenue, profit, P&L and performance from then on — it stays visible (greyed out, with an Undo return option) on the Rug Sales tab, and every return is listed in its own Returns report under Reports.
- Added "From Purchased Stock" to the "Bought from" list on the Rugs (inventory) tab, for rugs acquired as part of a purchased lot rather than from one named dealer. It's a regular rug source, so it can be renamed or removed in Settings → Rug sources just like any other.
- The "Rug from inventory" search on Rug Sales now shows matching stock rugs right in a list as you type — no more opening a dropdown to see the match. Just type a Rug ID or part of the description and click the rug you want.
- Added a search box above "Rug from inventory" on Rug Sales (and on each additional rug row) so picking a sold rug out of a stockroom of hundreds means typing its Rug ID or part of its description instead of scrolling a long dropdown.
- A cleaning order with more than one rug can now give each rug its own Rate $/sq ft, for when one rug on the order needs a different wash than the rest. A new rug defaults to the order's current rate so you only need to change it when it really differs; totals, invoices, and the order table all reflect each rug's own rate.
- Fixed: a cleaning order with several rugs could stretch a table row to hundreds of pixels tall, because the size text (e.g. "11'6" × 8'7" + 2'0" × 3'0"") could wrap after every single word instead of staying together rug by rug. Each rug's own size now stays on one line; a long list of rugs only wraps between whole rugs.
- Fixed: a removed cleaning vendor or rug source could quietly reappear after saving to the cloud. The record of "this name was deleted" only ever lived on the device you deleted it from, so any other device — or this one after a fresh reload — would see an old order still tagged with that name and silently recreate it. That record now syncs like everything else.
- Cleaning and Rug Sales now support more than one rug per order — click "+ Add another rug" to add extra rugs, each with its own size (cleaning) or its own rug ID, description, cost and price (sales). Totals, tax, invoices, and reports all add up across every rug in the order automatically.
- Added Add records from a file in Settings → Your data. Unlike Restore from backup (which replaces everything), this only adds records that aren't already here, so it's safe to use on a browser that already has data — nothing you've entered or fixed gets overwritten.
- Fixed: new default sample data baked into an update only ever showed up on a browser that had never saved anything. Once this browser saves data once, updates to the file itself no longer add to it automatically — new data now needs to come in through Add records from a file.
- Imported April–July 2026 order history from Shopify (cleaning, sales, padding, repairs).
- Added an Email field to Cleaning, Rug Sales, and Other Work.
- Added a Move to… option on Cleaning, Rug Sales, and Other Work rows, so a misfiled entry can be reclassified without retyping it.
- Imported March 2026 order history from Shopify.
- Fixed: expenses added by the Add this month's fixed costs button were saved on the device but never sent to the cloud, so they were missing on your other devices and would vanish if that browser was cleared.
- Fixed: deleting an invoice released its orders to be billed again, but only on the device you deleted it from.
- Fixed: Erase everything only cleared the device you pressed it on, and the cloud then restored the data. It now asks whether you mean this device or everywhere, and erasing everywhere really does reach the cloud and your other devices.
- Save to computer now names the file it wrote, so the button no longer looks like it did nothing.
- Fixed: the Save cleaning order button shared an internal name with the cloud settings button, which left it wired to nothing. Cleaning orders now save.
- Moved the Cloud saving panel out of the Today page and into Settings.
- Added this version number.
- First version live on the web, with cloud saving across devices.
Your data
Last backup 2026-07-25. Nothing new since.
Revenue mix this month
Money owed to you
Rate fills in from the service — override it any time. Leave the vendor cost at zero if you wash in house.
This order's price came in from Shopify and is locked to what was actually charged there — "Rate $/sq ft" and size here are for reference and won't change what you charge. Vendor cost still comes off it normally.
Cleaning orders — July 2026
Rug sales — July 2026
A rug's cost only hits the profit and loss in the month you sell it. Until then it sits here as stock.
All stock
Rug repairs — July 2026
Upload a Shopify order export
Same file every time: Settings → Export orders in Shopify admin, all orders, CSV for Excel. Column I (Subtotal) becomes the sales price, Column J (Shipping) is folded into that price and noted on the order, and Column K (Taxes) is stored exactly as Shopify calculated it. Each order is routed to Cleaning, Rug Sales, or Rug Repairs based on the line item name, and lands in that tab's regular table where you can edit, delete, or use "Move to…" if a guess is wrong. Re-uploading the same file is safe: orders already imported are skipped, only new ones are added.
Import history
Overhead only — rent, payroll, fuel, insurance. Money paid for a specific rug or a specific wash belongs on that order, so it lands in cost of sales instead.
Expenses — July 2026
Profit & loss statement
Cash basis, by order date. Sales tax collected is excluded from revenue — it is money you hold for the state.
Build an invoice
Work to include
Invoices issued
Every line
Reports
Cleaning services and rates
What you pay to have the rug washed is set per vendor, in the panel below.
Sales tax
Preset to 9.195% — the Boulder combined rate for 80304 (2.9% state, 1.335% county, 3.86% city, 1.1% special district), after the county went from 1.185% to 1.335% on 1 January 2026. Cleaning is set to untaxed because Colorado generally taxes goods rather than services. Both are starting points: confirm them with your accountant or the city Sales Tax Division before you file on these numbers.
Fixed monthly costs
Cleaning vendors
Set what each vendor charges you per square foot. Pick that vendor on a cleaning order and the cost fills itself in and comes straight off your gross profit.
Rates that differ by service
Optional. Leave a box empty and the vendor's standard rate above is used.
Rug sources
Who you buy rugs from. These are the choices in the Bought-from dropdown on rug sales and inventory, and they drive the sales-by-source report.
Expense categories
Renaming a category renames it on every expense already recorded.
Other-work categories
These are the choices in the Rug Repairs dropdown.
Invoice numbering
Order numbers are typed in by hand so they match your Shopify order. Only invoices are numbered for you, one above the highest already issued.
Your business details
This is the letterhead printed at the top of every invoice.
Set the budget —
Type a figure into any month. The year total keeps itself up to date, and the summary above shows where the whole year lands.
Cloud saving
Paste in the address and key from your Cloudflare setup. Every change is written to this browser first and sent up straight after, so the app keeps working if the shop internet drops.
Your data
Everything saves automatically in this browser. Download a backup regularly — that file is the only copy you can carry to another computer. Restore from backup replaces everything currently here; Add records from a file only adds what's new, so your own edits are never touched; Remove records from a file deletes only rows in inventory matching a Rug ID, vendor and Purchased/Consignment you list, and leaves everything else alone.
Last backup 2026-07-25. Nothing new since.