Rocon·Software Review

erp · 2026-11-03 · 8 min

The Undocumented Data Fields That Break Retail ERP Migrations

The undocumented fields that decide whether your ERP migration works

By the Rocon editors · last checked 2026-11-03

You have to decide whether to freeze order processing and run your data cutover this weekend, or delay the launch by three weeks to audit records you were told were already clean. If you proceed blindly, your sales counters will still take credit cards on Monday, but your stock counts will begin drifting by Thursday.

We have handled transitions off old on-premise accounting setups for small retailers running between five and fifteen terminals. The failure is rarely the product catalog or the customer names. The failure almost always stems from eight or nine database columns that do not show up on your standard PDF invoice or default export screens.

The sales engineers demonstrating cloud platforms call this “clean data onboarding.” We call it guessing. When you move an active business with six staff members from a desktop database to a hosted browser-based system, these undocumented structural gaps will decide if you balance your books at the end of the quarter.

The fields that disappear during standard exports

Most legacy point-of-sale systems run on older relational engines where decades of patches created quiet side tables. When you hit “Export Inventory” to a spreadsheet, the export script runs a clean query that flattens your operations. It drops the historical exceptions that your senior cashier understands instinctively but your new software treats as errors.

Tax calculation basis flags

Your old software probably stored both a flat tax amount and an internal flag indicating whether that tax was calculated line-by-line or calculated against the transaction subtotal. When moving to modern multi-tenant platforms, tax engines almost always force one standard model, usually line-item rounding driven by rules like RFC 4180 compliant CSV ingest pipelines that cast currency strings into strict floating-point or fixed-precision decimals.

If your legacy register calculated sales tax on the subtotal and rounded to the nearest cent at the very end of the ticket, you will see a one-cent variance on roughly one out of every seven multi-item receipts once imported into the new system. That does not sound catastrophic until your weekly sales report shows a non-zero balance between your merchant processing deposits and your general ledger liability account. We spent four days on one deployment tracking down an $18.42 tax disparity that was nothing more than three months of single-penny rounding divergences across twelve thousand sales.

Hidden unit of measure divisors

Small retail hardware and craft stores frequently sell items in split quantities: half-meters, fractional weights, or multi-packs broken down into singles. Legacy systems usually handled this through an unexposed multiplier column in the inventory record, often called something cryptic like CONV_FAC or PACK_QTY.

When you extract your SKU list, the export tool typically gives you the item description and the current retail price. If you sell a box of ten fasteners for twenty dollars, but your staff occasionally breaks the box to sell single pieces for two dollars, the old database kept that link via an invisible relational parent. Modern mid-market ERPs tend to demand that every individual unit have its own unique barcode and parent-child relationship clearly defined. If you import the legacy SKU without verifying the conversion divisor, your first purchase order will instruct your distributor to ship ten single fasteners instead of ten full cartons, or your registers will deplete ten boxes every time someone buys a single bolt.

Costing method timestamps

Every ERP vendor claims their software supports both average costing and standard FIFO (First-In, First-Out). What they omit is that your legacy software probably allowed back-dated inventory receipts without recalculating historical cost of goods sold.

If your inventory manager entered an invoice on Thursday for goods that were received on Monday, the old database accepted the transaction date silently. Modern inventory ledgers write an immutable timestamp at the exact millisecond the entry hits the database. If you migrate open balances without matching transaction timestamps to receipt dates, your opening margins in the new platform will swing wildly based on whichever arbitrary sequence the CSV importer used to process the file rows.

Ledger dates versus operational timestamps

We ran into our worst migration headache on a project where the store owner insisted their current trial balance was accurate to the dollar. It was, but only because the old desktop platform allowed two different definitions of “today.”

Legacy Database Schema:
[Ticket_Header] -> Date_Billed (User-selected date)
                -> Date_Posted (System clock when user closed batch)
                -> Date_Fulfilled (Physical pick date)

Modern SaaS Target:
[Order_Object]   -> created_at (Immutable server time)
                -> closed_at (Immutable server time)

The effective date mismatch

When a customer leaves a deposit on a special-order lawnmower in March, and picks up the machine in April, how does your current database tag that money? In older point-of-sale setups, cashiers could change the posting date on an invoice screen to match the physical arrival of the equipment.

Hosted cloud systems do not allow store clerks to override system clock timestamps, for sensible audit-trail reasons. If you migrate your open historical orders without separating the cash receipt timestamp from the fulfillment date, the imported data will register your deferred revenue as immediate income during the month of migration. We watched one business show a phantom forty percent spike in gross revenue for the first thirty days post-cutover because three hundred pending layaway tickets were imported with an active date flag instead of a pending liability flag.

Soft-deleted records and ghost IDs

Your old system almost certainly preserves deleted transactions using a boolean flag like IS_VOID or DELETED_OPT. The visual front-end hides these rows from your staff. You never see them during daily operations.

When you run raw database dumps or database-to-database API scripts, those deleted records often match the query criteria because they retain an active primary key. We once migrated what appeared to be 8,400 active customer accounts, only to find that 1,200 of them were duplicate profiles that had been “deleted” by store staff over a ten-year span. Because the new software required unique phone numbers for SMS receipts, the import choked on row 312: a deleted profile from five years earlier that shared a home landline with an active customer.

Data ElementLegacy Desktop BehaviorCloud ERP BehaviorImpact If Unmapped
Tax RoundingSubtotal rounding at transaction endLine-item rounding before sumWeekly general ledger imbalances of a few dollars
Quantity DecimalsFloats with arbitrary precisionStrict integer or enforced decimalsInability to sell partial lengths or weights
Transaction DatesBack-datable by terminal operatorsHard-locked system timestampsDistorted historical margin reports and deferred revenue
Deleted AccountsFlagged as hidden in the local UIExtracted as valid rows via raw SQLImport crashes due to duplicate telephone or email keys
Location CodesHardcoded text strings in line notesStrict Foreign Keys to warehouse tablesInventory arrives at virtual “null” storage bins

What breaks in month two

Month one is running on adrenaline. Your staff works through the interface changes, customers forgive slight checkout delays, and your inventory counts appear stable because you performed a manual floor count the weekend before launch.

The second month is where the structural cracks surface.

The first breakdown happens during your monthly supplier reconciliations. A vendor sends a credit memo for damaged goods returned six weeks ago—just before your cutover date. Your staff searches for the original purchase order in the new system. It does not exist, because you only migrated open purchase orders, not completed transactions from the prior fiscal quarter.

Your receiver has to manually enter a negative adjustment. If the old database tracked item cost using replacement cost while the new system calculates running weighted average cost, that credit memo will write off inventory value that the new system never recognized in the first place. You are now adjusting your balance sheet against inventory dollars that exist only on paper.

The second breakdown happens at the cash counter with customer returns without a physical receipt. In the legacy system, a cashier could look up a customer’s history across five years of flat transaction text. In the new system, historical tickets migrated as flat reference notes cannot be linked to the return processing engine.

Your cashiers, under pressure with four people standing in line, will use a generic “No Receipt Return” button to bypass the missing link. In doing so, they issue a store credit without returning the specific SKU to stock at its historical cost. By day forty-five, your inventory valuation has diverged from your physical stock counts, and you cannot tell if you are experiencing internal shrinkage or if your software is simply dropping cost linkages on returned merchandise.

A minimal audit before you cut over

Do not let an implementation partner tell you that data cleanup can take place after launch. Once you turn off your old terminals, you lose the ability to cross-check live transaction mechanics side-by-side.

First, pull fifty historical invoices at random: ten from last week, twenty from six months ago, and twenty from three years ago. Manually recalculate the line-item taxes, the applied discounts, and the net margin on each ticket using the calculation rules of your new software. If the numbers do not match to the penny, you have a rounding or discount attribution problem that needs fixing in the import mappings.

Second, verify your non-stock inventory IDs. Most stores have arbitrary codes like MISC, FREIGHT, or LABOR. Legacy systems allow you to sell these codes at arbitrary price points with variable tax statuses. Modern systems usually demand that an item code either be taxable or non-taxable, tracked or non-tracked. If you import an open order containing an untracked labor line that does not conform to the new system’s service-item rules, that order will freeze the nightly batch settlement until an administrator alters the database row directly.

Finally, confirm how your legacy platform stores customer addresses. If your old platform used a single text field for the entire street address, and your new system uses distinct fields for Street Address 1, Street Address 2, and Suite Number, an automated script will often shove the entire block into the first line. When you attempt to run fulfillment through an address validation API, those lines will fail, blocking your labels from printing during morning shipping runs.

If you are running a two-terminal retail operation with straightforward inventory, we would keep the old system running until the end of your financial year rather than executing a mid-year migration. If you are forced to migrate immediately due to failing local hardware or ending operating system support, we would drop historical transaction migration entirely: freeze the old database on a standalone laptop for historical lookup, import only your clean, physically counted on-hand inventory balances, and start the new system completely fresh on the first day of a new accounting month.