MerchantFlowMerchantFlow Docs
Profit & Loss

COGS Accuracy - Effective Dates, Coverage, and Recompute

Keep MerchantFlow COGS accurate with effective-dated entries, cost history badges, manual override precedence, coverage metrics, refund treatment, and recompute behavior.

COGS Accuracy

Accurate COGS is about more than typing in a number: it means the right cost, on the right variant, effective from the right date, in the right currency. MerchantFlow resolves the cost for every order line from your cost history, applies precedence rules between manual and imported entries, and recalculates profit automatically whenever costs change. This guide explains those mechanics so your margins stay trustworthy - and so you can tell the difference between a data problem and the system working as designed.

How to Access

Most of what this guide covers lives on Dashboard > P&L > COGS: the per-SKU Cost History modal, the coverage indicators in the page header, and the source badges in the table. Coverage warnings also appear on the main dashboard and the P&L page, noted below.

Effective Dates: Add a New Entry, Never Edit the Old One

Every cost entry has an effective date, and MerchantFlow resolves each order against the cost history: an order uses the most recent entry whose effective date is on or before the order date. Orders older than your first entry fall back to that earliest entry, so ancient orders still get a cost.

The golden rule when a supplier changes prices: add a new entry dated at the change - do not edit the existing entry.

Worked timeline. Your unit cost was $4.00 from launch; on July 1 the supplier raised it to $5.00:

You doJune orders resolve toJuly orders resolve to
Add a new entry: $5.00 effective July 1$4.00 (correct)$5.00 (correct)
Edit the old $4.00 entry to $5.00$5.00 (history rewritten)$5.00

Editing the old entry silently rewrites every historical margin. Adding a dated entry preserves history and switches cost exactly at the change.

Scheduled Price Changes

An entry with a future effective date is inert until its date arrives, then activates automatically. Scheduled entries are listed in the Upcoming Price Changes panel on the COGS page. Use "Schedule Price Change" when your supplier announces pricing ahead of time - see COGS Management for the step-by-step flow.

Reading the Cost History Modal

Open Cost History on any SKU or variant to see its full timeline. Each entry carries a status:

  • Active - the entry currently used for calculations
  • "Active - override" - a manual entry that is active and takes precedence over newer auto-synced entries
  • Overridden - an auto-synced entry that is recorded but not used, because a manual entry outranks it
  • Scheduled - a future-dated entry waiting for its effective date

When a cost held steady across many daily syncs, the history collapses the run into one card showing the first date it was set and the last date it was seen, marked "unchanged" - so a stable cost reads as one line, not ninety.

Which Entry Wins: Source Precedence

Every entry records its source, shown as a badge in the COGS table:

BadgeMeaning
MANUAL OVERRIDEEntered by you in MerchantFlow. Takes precedence over auto-synced entries and is never overwritten by a sync
SHOPIFY / WOOCOMMERCEAuto-synced from your store's cost fields
CSVImported from a CSV or BeProfit file
INVOICE_IMPORTWritten by the supplier invoice import
MIXED(Product row) variants have a mix of sources

The precedence rule: a manual entry beats any auto-synced entry - even a newer one. A Shopify sync can never clobber a cost you typed in; the synced value is recorded in history as Overridden instead. Invoice-import entries carry the same protection. The only way an import replaces manual entries is the explicit "Replace all costs with my store values" option - see Importing COGS.

Variant-Level Accuracy and Shared SKUs

Costs resolve at the most specific level available: a variant-level entry beats a SKU-level entry, which beats a product-level one. Variants of one product with different supplier costs should each carry their own entry.

The shared-SKU rule: when an order line has no variant identity and its SKU is shared across multiple variants with different costs, MerchantFlow deliberately counts that line as uncovered rather than guessing which variant's cost applies. Fabricating a cost would silently corrupt margins; a visible coverage gap tells you what to fix.

Recommendation: give every variant a unique SKU in your store. Unique SKUs eliminate ambiguity, make CSV imports precise, and keep coverage honest.

Coverage Metrics

Coverage tells you how much of your sales have a known cost:

  • Product coverage - share of products with a cost entry (the "Cost Coverage" KPI on the COGS page)
  • Unit coverage - share of sold units whose line resolved to a cost
  • Revenue coverage - share of revenue with known cost; the most important one, since your best sellers dominate profit

Where warnings appear:

  • The main dashboard shows an amber pill when unit coverage drops below 90%: "{n}% of sold units have no cost data", with a tooltip warning that margin is likely overstated
  • The P&L page header shows a "COGS Coverage" percentage

Target above 90% revenue coverage. Below that, gross margin figures flatter you - uncovered units contribute revenue with zero cost.

Coverage can read below 100% even with a fully costed catalog: shared-SKU ambiguity (above) and refunded-but-never-fulfilled orders (below) both exclude units by design.

Refunds and COGS

A refunded order keeps its COGS only if the order was actually fulfilled - you paid for goods that shipped. A refunded order that was never fulfilled has its COGS excluded from the P&L entirely (the goods stayed in inventory). This is binary per order, so a partially refunded, unfulfilled order drops all of its COGS.

The Refund Cost Recognition setting in Settings > Financial Preferences controls when a refunded order's costs count:

  • "On the sale date" (default) - costs stay on the order date, lining up with the revenue they produced
  • "On the refund date" - costs move to the day the refund happened

This setting changes how stored figures are read - switching it never rewrites or recalculates data.

Currency Rules

Everything cost-related is in your store currency: COGS entries, handling, fulfillment rates, country rates, and CSV imports. There are no per-entry currency conversions (the supplier invoice import is the one exception - it asks for an exchange rate).

One consequence worth knowing: orders placed in a different currency than your store currency are excluded from the P&L entirely - both their revenue and their costs. They are not converted. Margins stay internally consistent, but if part of your volume sells in another currency, your P&L understates total volume by that share.

Recompute Behavior: Why Pages May Briefly Disagree

Any cost change - adding, editing, or deleting an entry, importing a file, changing fulfillment rates - triggers an automatic rebuild of your profit history, starting from your oldest order (because the earliest entry backfills orders that predate it).

What you will observe:

  • The P&L page updates immediately for date ranges up to 90 days - it computes COGS live from the current cost history
  • Product-level profit and per-order margins lag until the background rebuild finishes - minutes on most stores, longer on very large ones
  • Briefly, the products table and the P&L page can disagree. That is the rebuild in flight, not data loss - check back shortly

Handling Costs

A cost entry can carry a per-unit handling cost alongside the unit cost. Handling is folded into the COGS line of the P&L (not fulfillment): every sold unit books unit cost + handling.

Two sharp edges:

  • Handling can currently only be loaded via the BeProfit import (its handling_cost / handling / shipping_cost columns) - there is no handling input on the COGS page and no handling column in the generic CSV. See Importing COGS.

Note: Editing a cost manually (inline edit, bulk update, mass update) writes a fresh entry with handling reset to 0 for that SKU from that date. If you rely on imported handling costs, re-import them after bulk edits or fold handling into the unit cost instead.

Best Practices

1. Date Entries at the Change, Never Edit History

New supplier price - new entry with the change date. Reserve edits for correcting genuine data-entry mistakes, accepting that they rewrite history.

2. Watch Revenue Coverage Weekly

Keep revenue coverage above 90%. Start with your best sellers - covering the top 20% of products typically covers 80% of revenue.

3. Keep SKUs Unique per Variant

Unique SKUs remove ambiguity from cost resolution, imports, and coverage. Shared SKUs are the most common cause of "coverage will not reach 100%".

4. Expect Brief Lag After Edits

After a cost change, give the background rebuild a few minutes before comparing pages. Persistent disagreement after an hour is worth reporting; disagreement two minutes after an edit is the system working.

Troubleshooting

Coverage is lower than expected despite entries everywhere

Cause: Shared SKUs across variants (ambiguous lines count as uncovered) or refunded-never-fulfilled orders (COGS excluded by design, units still counted). Solution: Give variants unique SKUs and re-sync. The refund effect is correct behavior - those units genuinely carry no cost in the P&L.

The dashboard and product pages disagree after a cost edit

Cause: The P&L computes COGS live; product-level figures wait for the background rebuild. Solution: Wait a few minutes. If the gap persists beyond an hour on a normal-sized store, contact support at [email protected].

A Shopify sync did not update a cost

Cause: That SKU has a manual entry, which outranks synced values - the synced cost is recorded as Overridden. Solution: This is by design. To let store values win, use "Replace all costs with my store values" in the import modal - see Importing COGS.

Handling cost dropped to zero

Cause: A manual cost edit wrote a fresh entry with handling reset to 0. Solution: Re-import handling via the BeProfit tab, or include handling in the unit cost going forward.

Frequently Asked Questions

Will editing a cost rewrite my historical profit?

Editing an existing entry - yes, that is exactly what it does, back to the previous entry's boundary. Adding a new entry with an effective date - no, history before that date keeps the older cost. When in doubt, add rather than edit.

Why do refunded orders count against my coverage?

Refunded-never-fulfilled orders have their COGS deliberately excluded while their units still count in the denominator. It is a signal of refund volume, not missing data.

What does the "Reconstructed" badge on a product mean?

The product was deleted in your store, and MerchantFlow rebuilt it from order history so those historical sales stay attributable. Reconstructed products have no store cost to sync - set their cost manually so historical margins are accurate.

How are warranty or replacement orders handled?

Zero-revenue warranty orders still carry fulfillment cost. Settings > Financial Preferences > Warranty Order Detection lets MerchantFlow identify them (by zero revenue, SKU prefix, or specific products) and report what warranty fulfillment costs you. Their costs are categorized, not excluded.

Why is an order missing from the P&L entirely?

Most likely it was placed in a currency different from your store currency - such orders are excluded rather than converted, on both the revenue and cost side.

Does changing Refund Cost Recognition recalculate anything?

No. It is a read-time choice between two views of the same stored data - switching it is instant and reversible.

Related Guides


Last updated: July 31, 2026