The problem
A price list spreadsheet starts as a tidy grid. Item, description, list price, currency, unit, maybe a discount band. Then reality arrives. One customer gets a special price. A region needs its own book. A promo has an end date. Someone adds a tab called final_v3 and emails it around.
The trouble is not the grid. It is the copies. Sales works from a download, finance works from the shared drive, support asks which number is live. A hidden row can carry last year's price. A broken formula can show a blank. Two people can edit the same cell and the last save wins. When a customer disputes a price, nobody can prove who changed it or when it took effect.
Spreadsheet controls are weak for this job. Sheet protection is easy to bypass. A shared link gives away more rows than intended. Version history shows cell edits but not the reason. You end up reconciling price changes through chat and email. That is the point where a small app earns its place.
What a good solution looks like
A good price list app does one job: it holds the current price for an item in a given price book, currency and period, and it shows how that price got there. Keep the scope tight. It is not a quote builder and not a billing engine. It answers a price question in seconds and keeps a record of every change.
The core records are simple. An item table holds SKU, name, unit and status. A price book table holds market, channel or customer group. A price entry points to the item and price book, then stores amount as a decimal, currency code, effective from date, effective to date and state: draft, active or retired. Customer overrides can be their own table, linked to the customer and the base price entry.
Roles matter more than screens. Viewers search and export. Editors propose changes. Approvers release a change to active. Admins manage users and correct mistakes with a reason. Every change writes to an audit log with user, time, old value and new value. Draft prices stay invisible to sales until approved.
The screen people use every day is a searchable table with filters for price book, currency, status and effective date. A detail panel shows current price, next price, history and any customer overrides. Bulk import should preview rows before it writes. Exports should respect the same filters, so finance gets a clean CSV that matches what sales sees.
How to build it
Start with the price list you have, not an ideal one. Pick one price book and one team. List the fields that people actually use. Write down five real price questions and the steps someone takes to answer them today. That list becomes your acceptance test.
Model the data before the UI. Use a relational database such as Postgres. Create tables for items, price books, prices, customers, overrides, users and change log. Add database constraints: unique item, price book, currency and effective date; amount must be zero or greater; currency must be a three letter code. Store money as decimal, never as a floating point number. Add a version column to each price row so two edits cannot silently overwrite each other.
Build the smallest workflow that can be trusted. Sign in through your identity provider so leavers lose access when their account is disabled. Map groups to viewer, editor, approver and admin. The main write action is propose a price change: choose item, price book, currency, amount, effective date and reason. Save it as draft. An approver reviews the old value and new value and sets it active. Past dates are locked unless an admin makes a correction and records why.
Do the import and export early. A CSV import with a dry run catches bad headers, duplicate rows and unknown SKUs before they reach the table. Keep the import report. Export to CSV with the active filters, and if finance or BI needs a feed, add a scheduled export or a read only endpoint. Test with messy rows: a missing currency, an end date before a start date, a price with a comma as decimal separator. Ship behind your SSO and keep the old spreadsheet read only.
Risks and how to manage them
The first risk is a new source of truth that nobody trusts. People will keep a private copy if the app is slow, hard to search or missing a field. Run a parallel week. Compare exports from the app against the old sheet by SKU and price book. Check row counts, spot check high value items, and fix gaps before you switch off edits.
The second risk is silent overwrites and bad dates. Use approvals for changes, especially for customer overrides. Lock past effective dates. Show time zone on every date field, and decide whether effective dates mean the start of the day in your head office or the customer's market. Keep an immutable change log. Do not hard delete a price entry. Retire it with an end date.
The third risk is import damage. A CSV can wipe or duplicate a price book if the rules are loose. Import into a staging table first. Validate every row. Show a summary of creates, updates and rejects before you commit. Require a reason for bulk changes. Keep a copy of the uploaded file and the report.
The fourth risk is scope creep. A price list app can grow into quoting, approvals for discounts, margin rules and billing. Each one adds rules that need owners. Keep the first version to price storage, search, change history and export. Put other requests on a list and review after the team has used the app for a month. Overbuilding is how small tools get abandoned.
How to measure success
Measure the work the app removes. Count the price questions answered from the app instead of chat. Track the time from a price request to an approved change. Count support tickets about stale prices. Count exports that fail validation. Take a baseline before launch and review the same counts after four weeks.
Check trust, not just speed. Ask finance whether the export matches the app. Ask sales whether they can find a customer override without asking. Ask an approver whether they can see the old value and the reason for each change. If people still keep a personal copy, the app is missing something or the old sheet is still editable.
Watch adoption by role. Viewers should sign in without training. Editors should need one short session. Approvers should clear their queue before effective dates. If approvals sit untouched, the workflow is too heavy or the wrong people have the role. Fix the role map before you add features.
If you want a fixed path, Cloudverg's Internal tool sprint is a $16,500 fixed price, four weeks, with sign in, roles, change history, import, exports and a runbook. It suits one workflow. Compare that with building in house, buying a large pricing platform, or keeping a tightly controlled sheet. For a single price list process, the small app is often the smallest useful step.
Frequently asked questions
How do I stop people from editing an old price list spreadsheet?
Make the old sheet read only and move edits to the app. Give each role a clear job: viewers search and export, editors propose, approvers release. Keep the old file visible for reference during a short parallel run, then archive it with a link to the app.
What fields should a price list app include?
At minimum: item or SKU, price book, amount, currency, unit, effective from date, effective to date and status. Add customer overrides as a separate table, plus a reason field and a change log. Skip fields nobody uses in the first month.
Should the price list app integrate with our ERP or CRM?
Only if the integration removes a real manual step. A scheduled CSV export to finance is often enough at first. Add a direct API link when a quote, order or invoice system needs live prices and you can support the failure cases.