
Cogs Tracking Allocation
- 69 installs
- 41 repo stars
- Updated March 13, 2026
- finsilabs/awesome-ecommerce-skills
Track cost of goods sold and landed costs via platform tools or accounting integrations to compute accurate gross margin per order.
About
A skill for tracking COGS and landed costs to know true gross margin on every order using platform cost fields and accounting integrations. A developer uses it to get accurate per-order margins rather than revenue-only figures.
- Per-product cost price feeding QuickBooks/Xero COGS entries
- Landed-cost allocation for freight, customs, and duties
Cogs Tracking Allocation by the numbers
- 69 all-time installs (skills.sh)
- Ranked #556 of 1,106 Finance & Trading skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/finsilabs/awesome-ecommerce-skills --skill cogs-tracking-allocationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 69 |
|---|---|
| repo stars | ★ 41 |
| Last updated | March 13, 2026 |
| Repository | finsilabs/awesome-ecommerce-skills ↗ |
What it does
Track cost of goods sold and landed costs via platform tools or accounting integrations to compute accurate gross margin per order.
Files
COGS Tracking and Allocation
Overview
Tracking Cost of Goods Sold (COGS) tells you the actual gross margin on every order — revenue minus what you paid for the products you sold. Most platforms let you enter a cost price per product, and accounting integrations (QuickBooks, Xero) use that to generate COGS entries automatically. Landed cost allocation (freight, customs, duties) requires either a dedicated app or manual allocation in your accounting software. Only build a custom COGS system if your platform cannot meet your costing method requirements (FIFO, weighted average).
When to Use This Skill
- When your income statement shows revenue but you cannot compute gross margin because unit costs are not tracked
- When importing goods internationally and needing to allocate freight, customs, and duties into the landed cost of each SKU
- When switching from periodic (year-end count) to perpetual (real-time) cost tracking
- When building variance analysis reports to identify SKUs where actual purchase costs are drifting from standard costs
- When an ERP integration (QuickBooks, NetSuite, Xero) requires COGS journal entries at time of sale
Core Instructions
Step 1: Determine platform and choose the right approach
| Platform | Recommended Approach | Why |
|---|---|---|
| Shopify | Enter cost per variant in Admin; use Shopify Analytics or connect QuickBooks/Xero for COGS reporting | Shopify stores cost price per variant; profit reports use this for margin calculation |
| WooCommerce | Enter purchase price per product; connect WooCommerce Bookings + accounting plugin or Metorik for margin reports | WooCommerce stores cost price natively; Metorik provides profit analytics |
| BigCommerce | Purchase cost field per product; connect to QuickBooks via built-in integration | BigCommerce has a cost price field; the QuickBooks integration auto-posts COGS |
| Custom / Headless | Build a cost ledger with FIFO/weighted-avg logic and accounting journal entries | Required when none of the above integrations meet your costing method or reporting needs |
---
Step 2: Enter cost prices per product
Before any COGS reporting is possible, every product variant needs a cost price.
Shopify
1. Go to Admin → Products → [Product] → [Variant] 2. Under Pricing, enter the Cost per item field 3. Shopify's Analytics → Finances → Product sales by variant report will then show profit per product
For bulk cost updates: use Matrixify (App Store) to import a CSV with cost per SKU — the column is Variant Cost.
WooCommerce
1. Go to WooCommerce → Products → [Product] → Inventory tab 2. Enter the value in the Purchase cost field (requires WooCommerce Cost of Goods plugin or the field added by your theme/plugin) 3. For reporting: install Metorik or connect QuickBooks for WooCommerce — both read the cost field and generate gross margin reports
Popular COGS plugins for WooCommerce:
- WooCommerce Cost of Goods (SkyVerge) — adds cost field, generates margin reports
- Metorik — analytics dashboard showing profit per product, order, and channel
BigCommerce
1. Go to Products → [Product] → Pricing 2. Enter the value in the Cost Price field 3. Connect QuickBooks Online via Apps → BigCommerce for QuickBooks — it maps cost price to COGS entries automatically
---
Step 3: Connect accounting software for COGS journal entries
The cost price field alone only enables reporting inside the platform. For your P&L and balance sheet, connect an accounting integration that posts COGS when orders are fulfilled.
Shopify → QuickBooks / Xero
- QuickBooks Online: Install QuickBooks Connector by OneSaas from the Shopify App Store. Configure: Sales → Fulfilled orders post to COGS account; map products to QuickBooks items
- Xero: Install Xero by Amaka or A2X from the Shopify App Store. A2X is the most widely used — it batches daily Shopify sales into summarized Xero journal entries including COGS
A2X is strongly recommended for Shopify + Xero — it handles currency conversion, refunds, fees, and COGS automatically.
WooCommerce → QuickBooks / Xero
- QuickBooks: Install QuickBooks Commerce or MyWorks Sync (most reliable WooCommerce ↔ QuickBooks sync)
- Xero: Install Xero for WooCommerce by Zapier or Xero Bridge by Parex for direct sync
BigCommerce → QuickBooks
- Use the built-in BigCommerce for QuickBooks app from the Apps marketplace
- Configure COGS mapping under Settings → Accounting → Cost of Goods Sold account
---
Step 4: Set up landed cost allocation
Landed costs (freight, insurance, customs, duties) must be added to the product cost before the first sale to get accurate COGS.
For most merchants (manual method): 1. Receive your shipment and get the freight/customs invoice 2. Calculate the landed cost per unit: Total landed cost ÷ Total units received 3. Update the cost price in your platform to include the landed cost component 4. For allocation by value: (Product value / Total shipment value) × Total landed cost ÷ Units received
For Shopify merchants with frequent imports:
- Install Shopify Shipping Costs or LandedCost.app from the App Store
- These apps let you enter a shipment's landed costs and allocate them across received SKUs automatically
For accounting software users:
- In QuickBooks or Xero, use a landed cost allocation journal entry to add freight/duties to inventory asset value before goods are sold
---
Step 5: Run COGS and margin reports
Once cost prices are entered and accounting is connected:
Shopify
- Analytics → Finances → Profit by product — shows revenue, cost, and margin per variant
- Analytics → Reports → Product sales — filter by date range, includes units sold and profit
WooCommerce + Metorik
- Metorik → Reports → Profitability — gross margin by product, order, and time period
- Metorik also shows cost per order and margin %
QuickBooks / Xero
- P&L report — COGS line shows total cost of goods sold for the period
- Inventory valuation summary — current on-hand value per SKU
---
Custom / Headless
For headless storefronts needing perpetual inventory costing with FIFO, build a cost ledger:
// Cost layer model — one row per purchase order receipt
interface InventoryCostLayer {
variantId: string;
receiptDate: Date;
quantityReceived: number;
quantityRemaining: number; // Decrements as units are sold
unitCostCents: number; // Purchase price per unit
landedCostCents: number; // Allocated freight/duties per unit
}
// FIFO cost assignment when an order is fulfilled
async function assignCogsFifo(variantId: string, locationId: string, quantity: number, orderId: string) {
let remaining = quantity;
let totalCostCents = 0;
return db.transaction(async tx => {
// Consume oldest cost layers first (FIFO)
const layers = await tx.inventoryCostLayers.findAll({
where: { variantId, locationId, quantityRemaining: { gt: 0 } },
orderBy: { receiptDate: 'asc' },
});
for (const layer of layers) {
if (remaining <= 0) break;
const units = Math.min(remaining, layer.quantityRemaining);
const totalUnitCost = layer.unitCostCents + layer.landedCostCents;
await tx.inventoryCostLayers.update(layer.id, {
quantityRemaining: layer.quantityRemaining - units,
});
await tx.cogsEntries.create({
orderId, variantId, quantity: units,
unitCostCents: totalUnitCost,
costingMethod: 'fifo',
});
totalCostCents += units * totalUnitCost;
remaining -= units;
}
if (remaining > 0) throw new Error(`Insufficient cost layers for ${variantId}`);
return { totalCostCents };
});
}
// Allocate landed costs to a received shipment (by value)
async function allocateLandedCostsByValue(shipmentId: string, totalLandedCostCents: number) {
const layers = await db.inventoryCostLayers.findByShipment(shipmentId);
const totalValue = layers.reduce((s, l) => s + l.unitCostCents * l.quantityReceived, 0);
for (const layer of layers) {
const share = (layer.unitCostCents * layer.quantityReceived) / totalValue;
const perUnitLanded = Math.round((share * totalLandedCostCents) / layer.quantityReceived);
await db.inventoryCostLayers.update(layer.id, { landedCostCents: perUnitLanded });
}
}Best Practices
- Enter cost prices before your first import or purchase order receipt — COGS is only accurate for orders after costs are set; retroactive fixes require manual adjustments
- Include landed costs in unit cost before the first sale — freight and duties paid after goods are received but before sale must be allocated; otherwise COGS understates the true cost
- Choose one costing method (FIFO vs. weighted average) per product category and stick to it — switching mid-year requires a revaluation journal entry
- Reconcile platform profit reports with your accounting software monthly — discrepancies usually mean cost prices are missing for some variants
- Set a standard cost at the start of each fiscal year for variance reporting — compare actual purchase prices to standard to catch cost drift early
Common Pitfalls
| Problem | Solution |
|---|---|
| Gross margin reports show 100% for some products | Cost price is missing for those variants; Shopify and WooCommerce silently treat missing cost as $0 |
| COGS in QuickBooks doesn't match the platform's profit report | The accounting integration may be using a different COGS account or ignoring refunds; check the integration mapping settings |
| Landed costs not reflected in COGS | Landed costs must be entered before the first sale; entering them after requires adjusting the cost layer manually in your accounting software |
| Cost price includes VAT but shouldn't | Enter the ex-VAT cost price; tax is a separate line in your P&L, not part of COGS |
| Weighted average cost goes stale | Recalculate weighted average dynamically from current inventory layers — never cache it as a static field |
Related Skills
- @inventory-tracking
- @multi-warehouse
- @catalog-import-export
{
"context": "Tests whether the agent designs the COGS cost ledger schema with the correct tables, column types (BIGINT cents), generated columns, CHECK constraints, and versioning pattern for standard costs.",
"type": "weighted_checklist",
"checklist": [
{
"name": "inventory_cost_layers table",
"max_score": 7,
"description": "Schema includes an inventory_cost_layers table (or equivalently named table) tracking cost per purchase receipt"
},
{
"name": "cogs_entries table",
"max_score": 7,
"description": "Schema includes a cogs_entries table (or equivalently named table) recording cost assigned at sale time"
},
{
"name": "standard_costs table",
"max_score": 7,
"description": "Schema includes a standard_costs table (or equivalently named table) for budgeted cost per variant"
},
{
"name": "landed_cost_shipments table",
"max_score": 7,
"description": "Schema includes a landed_cost_shipments table (or equivalently named table) tracking inbound shipment costs"
},
{
"name": "landed_cost_allocations table",
"max_score": 7,
"description": "Schema includes a landed_cost_allocations table (or equivalently named table) linking shipments to cost layers"
},
{
"name": "BIGINT cents for monetary fields",
"max_score": 12,
"description": "All monetary cost columns (purchase price, landed cost, standard cost, etc.) use BIGINT or equivalent integer type — NOT DECIMAL/FLOAT/NUMERIC"
},
{
"name": "Generated total_unit_cost column",
"max_score": 10,
"description": "inventory_cost_layers has a computed/generated column that sums unit cost and landed cost per unit (GENERATED ALWAYS AS or equivalent), rather than requiring application code to maintain this sum"
},
{
"name": "Costing method constraint",
"max_score": 10,
"description": "The costing_method column has a CHECK or ENUM constraint restricting values to exactly 'fifo', 'lifo', and 'weighted_avg' (or 'weighted_average')"
},
{
"name": "Landed cost allocation method constraint",
"max_score": 10,
"description": "The allocation_method column on landed_cost_shipments has a CHECK or ENUM constraint restricting values to 'value', 'weight', 'quantity', and 'volume'"
},
{
"name": "Shipment status constraint",
"max_score": 10,
"description": "The status column on landed_cost_shipments has a CHECK or ENUM constraint restricting values to 'pending', 'allocated', and 'posted'"
},
{
"name": "Standard cost versioning",
"max_score": 8,
"description": "standard_costs table has both effective_from and effective_to date columns, where effective_to is nullable (NULL means currently active)"
},
{
"name": "Standard cost uniqueness",
"max_score": 5,
"description": "standard_costs table has a UNIQUE constraint on (variant_id, effective_from) to prevent duplicate effective dates per variant"
}
]
}
Perpetual Inventory Cost Tracking — Database Schema
Problem/Feature Description
A mid-sized online retailer is replacing their end-of-year spreadsheet inventory count with a real-time perpetual inventory cost system. They sell hundreds of SKUs across multiple product variants and warehouse locations. Some goods are imported internationally, so the total cost of a unit includes not just the purchase price but also freight, insurance, customs, and duties that arrive on separate invoices.
The finance team has three requirements. First, they want to be able to trace which purchase lots were consumed when any order ships, using the costing method of their choice (FIFO, LIFO, or weighted average). Second, they need to record the landed costs associated with each inbound shipment and spread those costs across the received inventory. Third, they want to run variance reports each month comparing what units actually cost against the budgeted standard costs they set at the start of the year.
Your job is to produce the SQL migration that creates the full schema for this system. The schema must support all these use cases and enforce valid states through the database itself.
Output Specification
Produce a single SQL file named schema.sql containing all table definitions. Include comments explaining the purpose of key columns where the naming alone might be ambiguous. Do not include seed data or application logic — just the table definitions.
{
"context": "Tests whether the agent implements FIFO and weighted average COGS assignment following the required patterns: transactional FIFO with correct layer ordering, explicit error on insufficient stock, dynamically computed weighted average using SQL aggregation, and null cost_layer_id for weighted average entries.",
"type": "weighted_checklist",
"checklist": [
{
"name": "FIFO uses transaction",
"max_score": 8,
"description": "The FIFO cost assignment function wraps all database operations (layer updates and COGS entry creation) inside a single database transaction"
},
{
"name": "FIFO layer ordering",
"max_score": 10,
"description": "The FIFO function orders cost layers by receipt_date ASC (oldest first), with a secondary sort on created_at ASC or equivalent tiebreaker"
},
{
"name": "FIFO filters remaining quantity",
"max_score": 8,
"description": "The FIFO function filters cost layers to only those with quantity_remaining > 0"
},
{
"name": "FIFO explicit error on stockout",
"max_score": 12,
"description": "The FIFO function throws or returns an error (does NOT silently skip or return 0) when there are insufficient cost layers to cover the requested quantity"
},
{
"name": "Weighted avg uses SQL aggregation",
"max_score": 12,
"description": "The weighted average function computes the average cost by querying the database (SUM of quantity_remaining * unit_cost / SUM of quantity_remaining), NOT by reading a pre-stored cached average field"
},
{
"name": "Weighted avg division safety",
"max_score": 8,
"description": "The weighted average SQL uses NULLIF or equivalent guard on the denominator to avoid division-by-zero, and COALESCE or equivalent to return 0 when there is no inventory"
},
{
"name": "Weighted avg cost_layer_id is null",
"max_score": 10,
"description": "The COGS entry created by the weighted average function sets cost_layer_id to null (since no single layer is being consumed)"
},
{
"name": "COGS at line level",
"max_score": 8,
"description": "Both functions accept and record an order_line_id (not just an order_id) on the COGS entry, enabling per-line margin analysis"
},
{
"name": "FIFO sets costing_method field",
"max_score": 6,
"description": "COGS entries created by the FIFO function set costing_method to 'fifo'"
},
{
"name": "Weighted avg sets costing_method field",
"max_score": 6,
"description": "COGS entries created by the weighted average function set costing_method to 'weighted_avg' (or 'weighted_average')"
},
{
"name": "FIFO consumes layers iteratively",
"max_score": 12,
"description": "The FIFO function iterates through multiple layers when a single layer does not have enough units, consuming from each layer in order until the full quantity is assigned"
}
]
}
Implement COGS Cost Assignment Functions
Problem/Feature Description
A warehouse management system already has an inventory_cost_layers table that records purchase lots (each row is a received batch of a given product variant at a given location, with a unit cost and remaining quantity). When an order ships, the system needs to post COGS — it must determine which purchase lots were consumed, record the cost, and reduce the available inventory in those lots.
The company runs two types of products: fast-moving consumables tracked with weighted average cost, and high-value electronics tracked with FIFO. Both methods need to be implemented. The COGS functions will be called inside a larger order fulfillment workflow, so correctness and data integrity are critical — any silent failures or stale cost data will cause the income statement to be wrong.
The engineering team lead has flagged two specific concerns from past incidents: (1) a prior implementation cached a running average per SKU and never recomputed it, causing margin reports to drift significantly after large receipts; and (2) another service used to silently skip COGS posting when inventory data was missing, hiding the problem for weeks. The new implementation must not repeat either mistake.
Output Specification
Write the COGS assignment logic in a file called cogs.ts. The file should contain:
- A function for FIFO cost assignment (
assignCogsFifoor similar) - A function for weighted average cost assignment (
assignCogsWeightedAvgor similar)
Assume a db object is available with methods db.transaction(), db.raw(), and ORM-style finders/updaters on each table. You do not need to make the code runnable — focus on the logic being correct. Add a brief comment in the file explaining any key design decisions.
{
"context": "Tests whether the agent implements landed cost allocation (with status guard, correct proration formula, layer updates, allocation records, and status transition) and a variance report (with time-bounded standard cost join, absolute variance ordering, and favorable/unfavorable classification).",
"type": "weighted_checklist",
"checklist": [
{
"name": "Pending status guard",
"max_score": 9,
"description": "The allocation function checks that the shipment's status is 'pending' before proceeding, and throws or returns an error if the shipment has already been allocated"
},
{
"name": "Proportional allocation formula",
"max_score": 9,
"description": "The allocation function computes each layer's share using (layer_basis / total_basis) * total_landed_cost, NOT by dividing total cost equally across layers"
},
{
"name": "Per-unit landed cost calculation",
"max_score": 9,
"description": "The allocated amount is further divided by the layer's quantity to produce a per-unit landed cost that is stored on the cost layer record"
},
{
"name": "Updates landed_cost_cents on layers",
"max_score": 9,
"description": "The allocation function updates the landed_cost_cents (or equivalent) field on each inventory_cost_layers record with the computed per-unit landed cost"
},
{
"name": "Creates allocation records",
"max_score": 8,
"description": "The allocation function inserts a row into landed_cost_allocations (or equivalent) for each layer, recording the shipment, layer, and allocated amount"
},
{
"name": "Marks shipment allocated",
"max_score": 8,
"description": "After processing all layers, the allocation function updates the shipment's status to 'allocated' (or 'posted')"
},
{
"name": "Variance SQL date-bounded standard cost join",
"max_score": 12,
"description": "The variance query joins standard_costs using a date range check: fulfilled_at date falls between effective_from and COALESCE(effective_to, a far-future date) — NOT a simple JOIN on variant_id alone"
},
{
"name": "Variance ordered by absolute difference",
"max_score": 10,
"description": "The variance query orders results by the absolute difference between actual and standard COGS (largest absolute variance first), NOT alphabetically or by volume"
},
{
"name": "Favorable/unfavorable classification",
"max_score": 10,
"description": "The variance report classifies each result as 'favorable' when actual cost is less than standard (negative variance), 'unfavorable' when actual exceeds standard (positive variance), and 'neutral' when equal"
},
{
"name": "Allocation inside transaction",
"max_score": 8,
"description": "The landed cost allocation function wraps the layer updates, allocation record inserts, and shipment status update inside a single database transaction"
},
{
"name": "Variance groups by variant",
"max_score": 8,
"description": "The variance query groups results by product variant (not by order or SKU batch), aggregating units_sold, actual COGS, and standard COGS at the variant level"
}
]
}
Landed Cost Allocation and Standard Cost Variance Report
Problem/Feature Description
A global electronics distributor imports components from three suppliers in Southeast Asia. Each inbound shipment carries freight, insurance, and customs charges that are invoiced separately from the goods — sometimes arriving weeks after the components themselves have been received and entered into the inventory system. The finance team needs a way to record these shipment-level charges and distribute them proportionally across the individual purchase lots that were included in each shipment.
Separately, the CFO has asked for a monthly report that compares what units actually cost (based on recorded COGS entries) against what the finance team budgeted they would cost (standard costs). The report should highlight the products drifting furthest from budget so the pricing team can act. The company sets new standard costs at the beginning of each fiscal year, and some SKUs have had their standards revised mid-year when a major supplier changed pricing — so the system must correctly match each COGS entry to whichever standard cost was active at the time of the sale.
Output Specification
Write the implementation in a file called cost-management.ts. It should contain:
- A function to allocate a shipment's landed costs across inventory cost layers (
allocateLandedCostsor similar) - A function or SQL query that computes standard cost variance per product variant for a given date range (
computeVarianceReportor similar)
Assume the database tables from the schema (inventory_cost_layers, landed_cost_shipments, landed_cost_allocations, standard_costs, cogs_entries, product_variants) are available via a db object. You do not need to make the code runnable. Add a brief comment explaining any important decisions.
{
"name": "finsi/cogs-tracking-allocation",
"version": "0.1.0",
"summary": "Track cost of goods sold with FIFO/LIFO/weighted average inventory valuation, landed cost allocation for imports, and variance analysis against standard costs",
"skills": {
"cogs-tracking-allocation": {
"path": "SKILL.md"
}
}
}