• Home
  • Login
Blog / framework

Aakvatech Limited - Avoid Backward Links in ERPNext Document Design

Good ERPNext customization respects document flow. When Document A creates Document B, Document A should not store a direct link to Document B.

May 26, 2026 · 7 min read

Avoid Backward Links in ERPNext Document Design

In ERPNext and Frappe development, document relationships should follow the business flow. If one document creates another document, the generated document should carry the reference back to the source.

In simple terms:

If DocType A creates DocType B, then DocType B may link to DocType A. DocType A should not normally link back to DocType B.

This principle avoids circular dependencies, improves reporting, keeps document history reliable, and aligns custom development with ERPNext’s own design patterns.

A common example is the relationship between Sales Order and Delivery Note.

A Sales Order can create one or more Delivery Notes. However, the Sales Order does not need a delivery_note Link field. Instead, the Delivery Note or its child table should reference the Sales Order.

The correct direction of links

ERPNext generally follows a forward-linking model.

A source document represents an intention, commitment, or request. A downstream document represents execution, fulfilment, billing, accounting, or movement.

For example:

Source document Downstream document Correct reference direction
Sales Order Delivery Note Delivery Note Item links to Sales Order
Sales Order Sales Invoice Sales Invoice Item links to Sales Order
Purchase Order Purchase Receipt Purchase Receipt Item links to Purchase Order
Purchase Order Purchase Invoice Purchase Invoice Item links to Purchase Order
Material Request Purchase Order Purchase Order Item links to Material Request
Delivery Note Sales Invoice Sales Invoice Item links to Delivery Note

The downstream document knows where it came from. The upstream document does not need to store every downstream result as a direct field.

Sales Order and Delivery Note example

A Sales Order may be delivered in many different ways.

One Sales Order can create:

  • one Delivery Note,
  • multiple Delivery Notes,
  • partial Delivery Notes,
  • Delivery Notes mixed with items from other Sales Orders,
  • amended or cancelled Delivery Notes,
  • or no Delivery Note at all.

Because of this, placing a single delivery_note Link field on the Sales Order would be structurally weak.

It assumes a one-to-one relationship where the real business process is often one-to-many or many-to-many.

The better model is:

  • Delivery Note Item contains a link to Sales Order.
  • Delivery Note Item contains a link to Sales Order Item.
  • If the entire Delivery Note is created from only one Sales Order, the parent Delivery Note may also carry a Sales Order reference for convenience.
  • The Sales Order remains clean and does not store a backward link to the Delivery Note.

This allows ERPNext to answer questions such as:

  • Which Sales Order created this Delivery Note line?
  • Which Sales Order Item was delivered?
  • How much has been delivered against each Sales Order Item?
  • Which Sales Orders are still pending delivery?
  • Which Delivery Notes were created from a Sales Order?

The key point is that these answers should be derived from downstream references, not stored as backward fields on the source document.

Why backward links create problems

Adding a backward link may look convenient at first. For example, a developer may think:

“Let us add a Delivery Note field on the Sales Order so users can quickly see the Delivery Note.”

This becomes problematic when the process grows.

1. It breaks one-to-many relationships

A single Sales Order can create many Delivery Notes. A single delivery_note field cannot represent that correctly.

Developers may then add a child table of Delivery Notes on the Sales Order. That also creates maintenance complexity because the source document must now be updated every time a downstream document is created, cancelled, amended, or deleted.

2. It creates synchronization risk

If Delivery Note is cancelled, amended, or deleted, what happens to the backward link on Sales Order?

If the Delivery Note is submitted but the Sales Order update fails, the system becomes inconsistent.

If a custom script updates the Sales Order but another process creates a Delivery Note differently, the backward link may be missing.

Forward references reduce this risk because the downstream document owns its origin reference.

3. It creates circular dependency

A clean document flow should look like this:

Sales Order → Delivery Note → Sales Invoice

A backward link creates this kind of structure:

Sales Order ↔ Delivery Note

This makes validation, reporting, cancellation, amendment, and permission logic harder to reason about.

4. It weakens auditability

ERP systems must preserve transactional history.

The Delivery Note is the evidence of delivery. Therefore, it should say which Sales Order it fulfilled. The Sales Order should not be forced to maintain a manually synchronized list of all delivery transactions.

The audit trail becomes stronger when execution documents carry their source references.

5. It conflicts with ERPNext reporting patterns

Many ERPNext reports calculate status from child table references and quantities.

For example, delivery status is not determined by a single Delivery Note link on the Sales Order. It is calculated by comparing ordered quantity, delivered quantity, returned quantity, and item-level references.

Backward fields can mislead developers and users into relying on incomplete shortcuts instead of actual transactional data.

Recommended design rule

Use this rule when designing custom DocTypes and custom flows:

The generated document should link to the source document. The source document should not link to the generated document unless there is a very specific, justified, and controlled reason.

In other words:

Allowed:
DocType B links to DocType A

Avoid:
DocType A links to DocType B

Where:

DocType A = Source document
DocType B = Generated downstream document

Applying this to custom DocTypes

Assume a custom DocType called Service Request creates another custom DocType called Service Job Card.

Avoid this:

Service Request
- service_job_card: Link to Service Job Card

Prefer this:

Service Job Card
- service_request: Link to Service Request

If Service Job Card has child rows, and the relationship is item-level or task-level, place the reference in the child table:

Service Job Card Item
- service_request: Link to Service Request
- service_request_item: Link to Service Request Item

This is especially important when partial fulfilment is possible.

When a parent-level forward link is acceptable

A forward link on the parent document is acceptable when the downstream document genuinely represents one source document.

For example, if a Delivery Note is created entirely from one Sales Order, a custom or standard field on Delivery Note may reference that Sales Order.

However, if the Delivery Note can contain items from multiple Sales Orders, the safer and more accurate reference belongs at the child table level:

Delivery Note Item
- against_sales_order
- so_detail

This preserves line-level traceability.

Practical implementation checklist

Before adding a Link field between two DocTypes, ask these questions:

1. Which document comes first?

The first document is usually the source. The later document should reference it.

2. Can one source create multiple downstream documents?

If yes, do not place a single backward Link field on the source document.

3. Can one downstream document combine multiple source documents?

If yes, put the source reference in the child table, not only on the parent.

4. Is the relationship line-level?

If quantities, items, tasks, or services are fulfilled partially, use child table references.

5. Can the downstream document be cancelled or amended?

If yes, avoid duplicating its reference back into the source unless you have a strong reason and reliable synchronization logic.

Recommended naming pattern

For custom forward links, use clear field names.

Examples:

service_request
service_request_item
against_sales_order
sales_order_item
reference_doctype
reference_name
source_document
source_document_item

Avoid vague names such as:

linked_doc
created_doc
generated_ref
back_reference

Clear naming makes reports, scripts, and future maintenance easier.

What to do when users want visibility from the source document

Sometimes users ask:

“Can we show the Delivery Notes inside the Sales Order?”

That does not mean you need a backward Link field.

Better options include:

Use a dashboard connection

Frappe supports dashboard-style document connections. This allows users to navigate related downstream documents without storing unnecessary fields.

Use a custom report

Create a report that shows all Delivery Notes linked to a Sales Order through Delivery Note Item references.

Use a button or query

Add a custom button such as View Delivery Notes that filters Delivery Notes using child table references.

Use computed indicators

If the business need is status visibility, show computed values such as:

  • delivered quantity,
  • pending quantity,
  • delivery percentage,
  • last delivery date,
  • latest Delivery Note reference.

These should be calculated from downstream records instead of manually stored as backward links.

The wrong design

Sales Order
- delivery_note: Link to Delivery Note

This is weak because a Sales Order may have multiple Delivery Notes.

The better design

Delivery Note Item
- sales_order: Link to Sales Order
- sales_order_item: Link to Sales Order Item

Optionally, when the Delivery Note is created from only one Sales Order:

Delivery Note
- sales_order: Link to Sales Order

This design supports both simple and complex fulfilment flows.

Final recommendation

When customizing ERPNext, always design document links in the direction of the transaction flow.

A source document should initiate the process. A downstream document should carry the reference to its source. This keeps the data model clean, scalable, auditable, and aligned with ERPNext’s standard architecture.

For the Sales Order and Delivery Note flow, the Sales Order should not store a Delivery Note link. The Delivery Note, and more accurately the Delivery Note Item, should store the Sales Order reference.

That is the safer and more ERPNext-native design.

Reference articles and discussions

  • No external reference articles or discussions were used.
  • Topic and example provided by Mitesh Choksi.
  • Draft prepared using Frappe and ERPNext implementation design experience.

Aakvatech Limited is a Frappe Gold Partner and ERPNext implementation company headquartered in Dar es Salaam, Tanzania, operating across East Africa and the UAE.

This article was co-created using AI to accelerate drafting, with final insights curated and validated by the author. Any customer, personal, or sensitive data referenced during drafting has been anonymized or masked where applicable. All contributors, reference URLs, tools, and materials used to assist this content curation are credited in the Reference section.

Published on May 26, 2026

Mitesh P Choksi

No comments yet. Login to start a new discussion Start a new discussion

Your Name
Email
Add a comment
Ctrl+Enter to add comment

Footer Logo
© Aakvatech Limited
  1. Office #6, 2th Floor 10 West Building, Vigunguti
  2. Julius K Nyerere Road,
  3. Dar es Salaam, Tanzania