ERPNext Guides

ERPNext Landed Cost Voucher: How to Add Freight & Duty to Item Cost (2026)

Use the ERPNext Landed Cost Voucher to add freight, customs duty and insurance to item valuation — how it works, how to create one, distribution methods, and copy-paste automation.

MManojJuly 11, 2026Updated July 24, 202611 min read
#erpnext#landed-cost#imports#costing
Share

A Landed Cost Voucher in ERPNext adds extra purchase costs — freight, customs duty, insurance, clearing charges — onto the valuation of the items you received, so your inventory value and cost of goods sold reflect the true landed cost, not just the supplier's invoice price. You create it against a Purchase Receipt and choose how the charges are distributed across items.

If you import goods or pay significant freight, the price on the supplier invoice is not what the stock actually costs you. Duty, shipping, insurance, and clearing agent fees can add 10–30% to the real cost. Booking those as plain expenses hides them from your item cost and quietly understates your cost of goods sold. The Landed Cost Voucher fixes exactly that.

The whole point of a Landed Cost Voucher is truthful inventory valuation: it pushes the "extra" costs of getting goods to your warehouse into the item's cost, so margins and COGS are real. I am Manoj, an ERPNext and Frappe implementation consultant at MithTech in Bengaluru, and I set these up for importers and distributors.

Try it: your real per-unit cost, live

Nudge the numbers to your actual last consignment. If additional costs come out to more than a couple of percent of the supplier invoice, booking them as plain expenses instead of an LCV is quietly overstating your gross margin.

CalculatorTrue Landed Cost Calculatorlink

Live calculator: supplier invoice + freight + duty + insurance + CHA + inland = true landed cost and per-unit landed cost.

Additional cost
₹132,500
freight + duty + ins + CHA + inland
Supplier invoice
₹500,000
True landed cost
₹632,500
Per-unit landed
₹633
Additional cost is 26.5% of the supplier invoice. Booking these as plain expenses hides that from item cost and understates COGS by the same amount. Indicative figures — verify against the actual freight / customs / CHA bills.

What is a Landed Cost Voucher in ERPNext?

A Landed Cost Voucher in ERPNext is a document that distributes additional purchase costs — such as freight, customs duty, insurance, and handling — across the items on a Purchase Receipt, increasing each item's valuation rate. It exists because the true cost of stock is the supplier price plus everything spent getting the goods into your warehouse, and those extra costs usually arrive on separate bills from freight forwarders and clearing agents.

Once posted, the voucher raises the valuation of the received items by their share of the landed costs. Your inventory is then valued at true landed cost, and when the items sell, the cost of goods sold includes freight and duty. This is what turns a rough margin into an accurate one for any business that imports or pays material inbound logistics.

Why every accounting standard says these costs belong in inventory

This is not an ERPNext design choice — it's what every major inventory standard requires. The definition of "cost of purchase" converges across regimes: all costs incurred in bringing inventory to its present location and condition are capitalised into inventory cost, not expensed as incurred. The LCV is simply the ERPNext mechanism that honours this.

  • Ind AS 2 / IAS 2 Inventories — cost of purchase comprises the purchase price, import duties and other non-recoverable taxes, and transport, handling and other costs directly attributable to acquisition (¶10–11).
  • US GAAP — ASC 330 Inventory — inventory cost includes all applicable expenditures directly or indirectly incurred in bringing an article to its existing condition and location (¶330-10-30-1).
  • UK GAAP — FRS 102 §13 — costs of purchase include import duties, transport, handling and other costs directly attributable to acquisition (§13.6).
  • CAS 1 (China) Inventories — same treatment: purchase costs include purchase price, taxes not deductible, transport, loading/unloading and other costs directly attributable to acquisition.

If freight and duty are material, expensing them instead of running an LCV isn't just an ERPNext bad habit — it fails the standard.

Skimmable summary: A Landed Cost Voucher distributes freight, duty, insurance, and handling across received items, raising their valuation to true landed cost. Inventory and cost of goods sold then reflect the real cost of getting goods to your warehouse — which is what Ind AS 2 / IAS 2 / ASC 330 / FRS 102 / CAS 1 all require.

How do I create a Landed Cost Voucher in ERPNext?

You create a Landed Cost Voucher in ERPNext by opening a new Landed Cost Voucher, selecting the relevant Purchase Receipt, adding the extra charges, choosing a distribution method, and submitting. The voucher then updates each item's valuation with its share of those charges. It should be posted while the items are still in stock so the cost attaches correctly.

Click through the demo below — each step shows what you do in the UI and what the ERPNext v16 controller does with your input, cited to file and line in the local checkout.

InteractiveLCV Step-Through Demolink

Four-step click-through: New LCV → Fetch PR → Fill Charges → Distribute and Submit, with the source-file citation for each stage.

Step 1 of 4
Open a new Landed Cost Voucher

Stock module → Landed Cost Voucher → New. Set Posting Date and Company. The naming series MAT-LCV-.YYYY.- is pre-wired.

What ERPNext does under the hood
Skeleton document with an empty purchase_receipts child table, taxes child table, and distribute_charges_based_on set to 'Qty' by default.
apps/erpnext/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.json (naming_series MAT-LCV-.YYYY.-)

Here is the same sequence as a Steps block for readers who prefer the linear form:

Open a new Landed Cost Voucher

Stock module → Landed Cost Voucher → New. Set Company and Posting Date. Naming series MAT-LCV-.YYYY.- is pre-wired in landed_cost_voucher.json.

Fetch the Purchase Receipt

In the Purchase Receipts child table add rows pointing at the GRN(s) you're landing costs against. Click Get Items From Purchase Receipts — the server method at landed_cost_voucher.py:56 pulls items via get_pr_items (landed_cost_voucher.py:421) and copies base_rate / base_amount into the LCV Item table.

Fill the Taxes & Charges child table

One row per charge — freight, customs BCD, insurance, CHA, inland transport — each with a Description, Expense Account (Indirect Expenses head), and Amount. validate_expense_accounts (landed_cost_voucher.py:178) refuses accounts belonging to a different company when perpetual inventory is enabled.

Choose distribution method and submit

Pick Distribute Charges Based OnAmount, Qty or Distribute Manually (the three enum values on the DocType). On submit, update_landed_cost at landed_cost_voucher.py:307 re-writes item.landed_cost_voucher_amount on the linked PR, then calls update_stock_ledger and make_gl_entries with via_landed_cost_voucher=True, and finally repost_future_sle_and_gle so units already consumed pick up the corrected valuation.

Pre-flight: check every charge row has an expense account

validate_expense_accounts throws an Incorrect Account error if any row in the Taxes & Charges table points at an account belonging to another company (or is blank). The error is opaque to end users — it looks like a data-entry mismatch. The Client Script in the Automation section below catches this on before_save so accounts hears about it before hitting submit.

Skimmable summary: Create a Landed Cost Voucher, fetch the Purchase Receipt, add each charge (freight, duty, insurance) in the charges table with its expense account, pick a distribution method, and submit. ERPNext updates item valuations, reposts SLEs and re-books GL entries — even for units already sold.

How are landed costs distributed across items?

Landed costs are distributed across items in ERPNext by Amount, Qty, or Distribute Manually, and the method you pick changes how fairly the cost lands on each item. Distribution by Amount spreads charges in proportion to each item's value; distribution by Qty spreads them per unit; Distribute Manually lets you assign exact shares when neither default is fair.

The core set_applicable_charges_on_item method at landed_cost_voucher.py:202 is where the split happens — it reads the enum value, scrubs it to a field name, and multiplies each item's share by the total charge. Weight-based distribution isn't in core; you need a small custom script that overrides this method to read total_weight instead.

Which method fits which charge type? Pick a charge below and the picker will tell you which basis to use on the LCV.

InteractiveDistribution Method Pickerlink

Pick a charge type (freight, insurance, customs, CHA, inland, bank) — get the recommended ERPNext Distribute Charges Based On value and one-line rationale.

Recommended method
Ocean / air freightQty (or weight, if items vary)

Freight is priced by weight or volume, not by invoice value.

Distribute Charges Based On: Qty Weight → custom script needed

Core ERPNext supports Amount / Qty / Distribute Manually out of the box (see landed_cost_voucher.py:44). Weight-based distribution needs a custom script that overrides set_applicable_charges_on_item.

Skimmable summary: Landed costs distribute by Amount (value share), Qty (per unit), or Distribute Manually. Freight and inland transport go by Qty (or weight if you customise), insurance / customs / CHA / bank charges by Amount. Weight distribution requires a custom script.

When should I use a Landed Cost Voucher?

You should use a Landed Cost Voucher whenever the extra costs of receiving goods are significant enough to matter to your item cost — chiefly imports with customs duty and freight, or any purchase with substantial inbound logistics. If freight and duty are trivial, booking them as expenses is fine; once they materially change item cost, they belong in valuation.

Importers are the clearest case: duty, ocean or air freight, insurance, and clearing agent fees together can be a large share of cost, and leaving them out makes every margin report wrong. Distributors with heavy inbound freight benefit too — the discipline is covered in my ERP guide for distributors and wholesalers, and the wider inventory picture in the ERPNext inventory management guide. For manufacturers, landed raw-material cost then flows into finished-goods costing and any standard costing variance analysis you run.

If your imports are in a foreign currency

The moment there's a foreign-currency element, a stale exchange rate on the Goods Receipt silently corrupts your inventory valuation before an LCV even gets involved. That's covered in a separate deep-dive with a live FX calculator, worked ledger example and copy-paste automation gate — ERPNext Landed Cost & FX Gone Wrong: the interactive fix guide.

Skimmable summary: Use a Landed Cost Voucher when inbound costs materially affect item cost — imports with duty and freight, or heavy inbound logistics. Trivial charges can stay as expenses; significant ones belong in valuation so margins and COGS stay accurate.

Automation: seed the LCV, gate the mistakes

The single biggest waste in a busy imports team is retyping the same freight / CHA / duty numbers from a clearing-agent PDF into a manual LCV every week. Three small automations remove that friction entirely — none of them need GitHub Actions or a paid CI service; they run on your existing bench scheduler or a self-hosted n8n.

Code recipeLCV Automation Recipelink

Three copy-paste automations: a Server Script that seeds a draft LCV on GRN submit, a Client Script that warns on missing charge accounts, and an n8n workflow that surfaces clearing-agent PDFs into Slack.

On Purchase Receipt submit, seed a draft Landed Cost Voucher with the freight/CHA charges already known from the item metadata or a linked freight PI. Accounts opens the draft, verifies figures and submits.

lcv_server.py
# Server Script → DocType Event → Purchase Receipt → on_submit
import frappe
from frappe.utils import flt

def after_purchase_receipt_submit(doc, method=None):
    if doc.currency == frappe.db.get_default("currency"):
        # skip pure-domestic GRNs unless you want LCV for them too
        return

    # Skip if we've already seeded one for this PR
    if frappe.db.exists("Landed Cost Voucher Purchase Receipt", {
        "receipt_document": doc.name, "docstatus": ["!=", 2]
    }):
        return

    lcv = frappe.new_doc("Landed Cost Voucher")
    lcv.company = doc.company
    lcv.posting_date = doc.posting_date
    lcv.distribute_charges_based_on = "Amount"
    lcv.append("purchase_receipts", {
        "receipt_document_type": "Purchase Receipt",
        "receipt_document": doc.name,
        "supplier": doc.supplier,
        "posting_date": doc.posting_date,
        "grand_total": doc.base_grand_total,
    })

    # ---- Fill in your actual heads here -----------------------------------
    #  These accounts must exist under the company's Indirect Expenses.
    #  Left as placeholders — swap for your chart-of-accounts codes.
    charges = [
        {"description": "Ocean freight",     "expense_account": "Freight & Forwarding - YC", "amount": 0.0},
        {"description": "Customs BCD",       "expense_account": "Customs Duty - YC",         "amount": 0.0},
        {"description": "CHA / clearing",    "expense_account": "Clearing Charges - YC",     "amount": 0.0},
        {"description": "Insurance premium", "expense_account": "Insurance - Import - YC",   "amount": 0.0},
    ]
    for c in charges:
        lcv.append("taxes", c)

    lcv.get_items_from_purchase_receipts()
    lcv.insert(ignore_permissions=True)  # DRAFT — accounts reviews & submits
    frappe.msgprint(f"Draft LCV {lcv.name} created against {doc.name}")

Deploy them in this order and you get the compounding effect: the n8n workflow makes sure the charge amounts land in a place someone will see, the Server Script pre-fills the draft so accounts only has to check and submit, and the Client Script stops the two errors that most commonly waste a submit attempt.

Landed cost is the entry point into a whole family of ERPNext costing questions — none of these are hypothetical, all of them are posts you can read next.

Import-heavy business? Get landed cost right.

I set up landed cost, valuation, and import workflows in ERPNext so your inventory and margins reflect true cost. See the ERPNext product page or, if you're in the trading hub, ERPNext implementation in Mumbai.

Frequently asked questions

+What is a Landed Cost Voucher used for in ERPNext?

It adds extra purchase costs — freight, customs duty, insurance, and clearing charges — to the valuation of received items so inventory is valued at true landed cost. It is created against a Purchase Receipt and distributes the charges across items, which makes COGS and margins accurate for importers and distributors.

+How do I add freight or customs duty to item cost in ERPNext?

Create a Landed Cost Voucher, fetch the Purchase Receipt for the shipment, and enter each charge in the Taxes & Charges table with its expense account. Choose Distribute Charges Based On (Amount / Qty / Manual) and submit. ERPNext raises each item's valuation rate by its share, so the cost is embedded in stock rather than booked as a plain expense.

+Can I add landed cost after the items are already sold?

Yes — update_landed_cost at landed_cost_voucher.py:307 reposts future SLEs, so units already consumed pick up the corrected valuation and the delta flows to COGS. The caveat is closed accounting periods: if your policy blocks reposting into them, book a manual Journal Entry in the current period instead.

+What distribution method should I use for landed costs?

Match the method to how the charge was incurred: Amount for value-based charges (customs BCD, insurance, CHA, bank), Qty for per-unit or per-weight charges (ocean freight, inland transport), and Distribute Manually only when neither default is fair. Use the picker widget above — it names the ERPNext enum value for each case.

+Which ERPNext version do the file references in this post apply to?

The code paths cited — landed_cost_voucher.py:56, landed_cost_voucher.py:307, stock_controller.py:1101, purchase_receipt.py:626 — are from the ERPNext v16 checkout (git tag v16.22.0-495-gde591661b9, effectively v16.28.x). The same functions exist in v14 and v15 with cosmetic differences; the LCV DocType itself has been stable since v11.

+Does the Landed Cost Voucher affect accounting as well as stock?

Yes. Submitting an LCV re-runs make_gl_entries(via_landed_cost_voucher=True) on the linked Purchase Receipt, which credits each charge's expense account (make_landed_cost_gl_entries at purchase_receipt.py:626) and debits the inventory account by the same amount. Stock valuation and general ledger stay consistent.

+What happens if we skip the LCV and just expense freight and duty?

Your inventory sits on the balance sheet at the supplier invoice value (understated), and your P&L shows the freight and duty as period expenses (COGS understated). Gross margin looks artificially high until the stock sells — and even then, it's the next period's COGS that gets hit, so margin comparability across periods is broken. It also fails the "cost of purchase" test under Ind AS 2, IAS 2, ASC 330 and FRS 102 §13.

About the author

Manoj is an ERPNext and Frappe implementation consultant at MithTech in Bengaluru. He configures landed cost, import workflows, and inventory valuation in ERPNext so importers and distributors get accurate item costs and margins.

Free · By email

Get practical ERPNext & automation guides

New implementation guides, cost breakdowns and open-source tips for Indian businesses — occasionally, straight to your inbox. No spam.

M

Written by

Manoj

Founder of Mith Tech, an open-source ERP & automation studio. Hands-on ERPNext/Frappe implementation across multi-branch, multi-warehouse Indian operations — GST/TDS/PT compliance, branch-level permissions, and custom Frappe apps that give management real-time visibility.

Keep reading

See what this looks like for your business

Book a free 30-minute audit. We'll map your workflows, find where time and money leak, and design an open-source stack you actually own — no per-user licence fees.

Book a consultation
0
Published on 11 July 2026

Manoj

Comments & ratings

No comments yet. Start a new discussion.